20190310のvue.jsに関する記事は3件です。

Carloでホットリロードしながら開発するためのwebpack-dev-serverの設定

話題の Carlo で何か作ってみようと思い、Vue CLI で作ったプロジェクトの開発モードと組み合わせようとして、環境設定に少しつまづいたのでメモ。

Carlo設定

main.js(Carlo起動スクリプト)
// Tell carlo where your web files are located.
app.serveOrigin('https://localhost:8080')

これにより localhost の内容が Carlo で表示されるようになります。
※開発中は上記の設定で、ビルド後は app.serveFolder(__dirname) 等を使用するよう、環境変数などで分岐を入れることになると思います。

webpack-dev-server設定

vue.config.js
module.exports = {
  devServer: {
    disableHostCheck: true,
    headers: {
      'Access-Control-Allow-Origin': 'https://domain'
    },
    host: 'localhost',
    https: true
  }
}

今回 Vue CLI なのでこのファイル名ですが、他の場合も webpack.config.js に同様の設定を追加すれば動くと思います。

経緯

最初、デフォルト設定の http://localhost:8080 を Carlo で読み込むように設定して起動したら画面が真っ白になっていて、 DevTools を開いたらJS等が読み込めていませんでした。
コンソールで location を調べると、 https://domain/index.html となっていたので、とりあえず HTTPS に変更してみたところ、画面は表示されましたがHMR部分でエラーが出ました。
あとはエラー内容をググりながら、 host → disableHostCheck → headers の順に追加したところで、ようやく HMR が動くようになりました。

おまけ

Carlo を立ち上げたときに Chrome DevTools も開く設定。(Chrome の起動オプションです。上記の Carlo の設定同様、開発モードのみ有効になるように調整する必要がありますね)

main.js(Carlo起動スクリプト)
  const app = await carlo.launch({
    args: ['--auto-open-devtools-for-tabs']
  })

また、localhost を HTTP 化した後に、「この接続はプライバシーが保護されません」という Chrome の警告画面が出るようになり、毎回許可するのが面倒だったので、上記 args に --allow-insecure-localhost を入れていたのですが、いま試しにはずしたら警告は表示されなくなっていた……。devServer の設定を https だけに戻しても警告は出ないので、一度設定したら出なくなるのかも?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(備忘録)Vue.js + Firebase Hosting を用いたWebサイト作成

1. はじめに

2019年3月9日にUEQareer様主催にて開催されたFirebase勉強会でのVue.js + Firebase Hosting を用いたWebサイト作成について、自分への備忘録としてまとめてみました。ご参考になれば幸いです。

2. 学べる内容

  • Vue.js
  • vue-cliコマンド操作
  • Firebase
  • メール認証
  • Googleアカウント認証
  • Realtime Database
  • firebase-toolsコマンド操作
  • Firebase Hosting

3. 学習サイト

4. コマンドメモ

# vue-cliのインストール
$ sudo yarn global add @vue/cli

# vueコマンドのバージョン確認
$ vue --version

# vue GUIの実行
$ vue ui

# vue GUIをブラウザで表示
localhost:8000/dashbord
localhost:8080/project/create

# プロジェクトマネージャに移動して作成をクリックする
# vue-todo
# デフォルトプリセット
# (5分くらい時間がかかる)

# http://localhost:8080/
# http://localhost:8080/signin
# http://localhost:8080/signup

# firebase-toolsのインストール
$ sudo yarn global add firebase-tools

# ローカル環境の作業中vueプロジェクトフォルダに移動
$ cd firebase-todo/

# Firebaseログイン
$ firebase login

# Firebaseプロジェクトの設定
$ firebase init

# firebase initで当該Firebaseプロジェクトが表示されなかった場合
$ firebase init --project <FirebaseプロジェクトID>

# デプロイ
$ firebase deploy

# デプロイ後の完成したWebサイトへのアクセス
https://XXX-XXXX-99999.firebaseapp.com

5. おわりに

Vue.js学習の参考になれば幸いです。
ハンズオン開催してくださいましたUEQareer様、感謝いたします。

2019/03/09 TAKAHIRO NISHIZONO

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TypeScript の Vue.extend(options) で options の型を明示せず data などの同時指定時に props の default がアロー関数でないと型の解釈ができなくなる

TypeScript の Vue.extend(options) で options の型を明示せず data などの同時指定時に props の default がアロー関数でないと型の解釈ができなくなる

とりあえず試したのは VSCode, Vetur, nuxt-ts の環境です。

Vue.js での TypeScript 使用の前提

前提として・・・ Vue.js で TypeScript を使用する際にはnoImplicitThis を true にしましょう。
this の推論が効くようになり data や props などの定義が見れるようになります。

tsconfig.json
{
  "compilerOptions": {
    "noImplicitThis": true
  }
}

this の推論

TypeScript のサポート - Vue.js

コンポーネントメソッド内で this の型をチェックするには strict: true (もしくは最低でも strict フラグの一部の noImplicitThis: true) を含める必要があることに注意してください。

props の推論の事例

options に型を指定しないケース

options-any-props
<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  props: {
    propId: {
      type: Number,
      default() {
        return 1;
      },
    },
  },
  mounted() {
    this.propId;
  },
});
</script>

単純に propId を定義しており、下記のようにその型が推論されています。

推論された props

こちらに data を指定すると・・・

options-any-props-data
<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  props: {
    propId: {
      type: Number,
      default() {
        return 1;
      },
    },
  },
  // こちらに data を指定
  data() {
    return {
      name: 'Taro',
    };
  },
  mounted() {
    this.propId;
  },
});
</script>

propId が any に

propIdany となりさらにエラー扱いになってしまいました。
一方で data に指定した name は正しく解釈されています。

props は推論されないが data は推論される

props の default をアロー関数にしてみる

これといって根拠がないんですが・・・いじっていたところ動いたケースとして
props の default の指定をアロー関数にしてみます。

options-any-props-default-arrow-function
<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  props: {
    propId: {
      type: Number,
      // 通常の関数のメソッド指定からアロー関数の指定に
      // default() {
      default: () => {
        return 1;
      },
    },
  },
  data() {
    return {
      name: 'Taro',
    };
  },
  mounted() {
    this.propId;
  },
});
</script>

エラーが解消されて推論された props

先ほどでていたエラーは消え data と併用しつつ propId が推論されています。

options に型を指定してみる

options の型に指定する ThisTypedComponentOptionsWithRecordProps

Vue.extend() の定義は node_modules/vue/types/vue.d.ts にあり、
引数の指定の仕方によりオーバーロード?をして処理の流れを切り替えているようです。

node_modules/vue/types/vue.d.ts
export interface VueConstructor<V extends Vue = Vue> {
  new <Data = object, Methods = object, Computed = object, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): CombinedVueInstance<V, Data, Methods, Computed, Record<PropNames, any>>;
  // ideally, the return type should just contain Props, not Record<keyof Props, any>. But TS requires to have Base constructors with the same return type.
  new <Data = object, Methods = object, Computed = object, Props = object>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): CombinedVueInstance<V, Data, Methods, Computed, Record<keyof Props, any>>;
  new (options?: ComponentOptions<V>): CombinedVueInstance<V, object, object, object, Record<keyof object, any>>;

  extend<Data, Methods, Computed, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, any>>;
  extend<Data, Methods, Computed, Props>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;
  extend<PropNames extends string = never>(definition: FunctionalComponentOptions<Record<PropNames, any>, PropNames[]>): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>>;
  extend<Props>(definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;
  extend(options?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;

extend の記述は 5 箇所のようですが・・・これまでの記述を踏襲するとすると
PropsObject となるような ThisTypedComponentOptionsWithRecordProps が適当そうです。
ThisTypedComponentOptionsWithRecordPropsnode_modules/vue/types/options.d.ts に定義があり・・・

node_modules/vue/types/options.d.ts
/**
 * This type should be used when an object mapped to `PropOptions` is used for a component's `props` value.
 */
export type ThisTypedComponentOptionsWithRecordProps
  // この改行はないですみやすさのためです
  <V extends Vue, Data, Methods, Computed, Props> =
  object &
  ComponentOptions<V, DataDef<Data, Props, V>, Methods, Computed, RecordPropsDefinition<Props>, Props> &
  ThisType<CombinedVueInstance<V, Data, Methods, Computed, Readonly<Props>>>;

使用するための型定義として Vue に加え、 Data, Methods, Computed, Propsinterface が必要そうです。

実際の型の指定事例

options-typed
<script lang="ts">
import Vue from 'vue';
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options';

interface Data {
  name: string;
}
interface Methods {}
interface Computed {}
interface Props {
  propId: number;
  propAidei: string;
}

const options: ThisTypedComponentOptionsWithRecordProps<
  Vue,
  Data,
  Methods,
  Computed,
  Props
> = {
  props: {
    propId: {
      type: Number,
      default() {
        return 1;
      },
    },
    propAidei: {
      type: String,
      default: () => {
        return 'ichi';
      },
    },
  },
  data() {
    return {
      name: 'Jiro',
    };
  },
  mounted() {
    this.propId;
    this.propAidei;
  },
};

export default Vue.extend(options);
</script>

Methods, Computed については空の interface にしています。
さらに props の指定に通常の関数、アロー関数それぞれを指定していますが・・・

通常関数、アロー関数それぞれの props

エラーは発生せず props の推論も正しく行われています。

this の型

ちなみに this の型はこんな感じになっています。

this の型

interface でそれぞれ定義された Props などが & により Union Type になっているようです。
Union Types - Advanced Types - TypeScript

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む