54
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue + TypeScript 早期体験

Last updated at Posted at 2017-10-10

Vue.version < 2.5 && Vue.version >= 2.2 適用される

公式ドキュメントによるやり方

Vue 2.2 から、Vue にはいろんな公式型宣言が提供してあるので、さっそく、単一ファイルコンポーネントで TypeScript を試してみましょう。

webpack rules に ts-loader 相関を添付しましょう(こっちは webpack2)

webpack.base.conf.js
module: {
  rules: [
+   {
+     test: /\.ts$/,
+     exclude: /node_modules|vue\/src/,
+     loader: 'ts-loader',
+     options: {
+       appendTsSuffixTo: [/\.vue$/]
+     }
+   },
    ...

.ts のファイルを ts-loader で読み込む
appendTsSuffixToは vue を module として tsc でプロセスして、module not found の問題を解決する(tsc は .vue ファイルが知らない)

.d.ts ファイルを作成する

どんな名前でも、どこでも、tsconfig.json の include PATH にあればいいので、必ず .d.ts を名前の終わりにつけます。

sfc.vue.d.ts
declare module "*.vue" {
  import Vue from 'vue'
  export default Vue
}

vscode の .ts ファイルに .vueファイルも知らせます。

tsconfig.json を作成する

tsconfig.json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "isolatedModules": false,
    "target": "es5"
  },
  "include": [
    "./src/**/*.ts"
  ]
}

allowSyntheticDefaultImports は es6 の import を直接使える option です。

準備万端、npm run dev いきましょう!

こっちは vue-cli の webpack boilerplate を例として、Hello.vue を改造しましょう。

html template の msg の下に

Hello.vue/template
  <h1>{{ msg }}</h1>
+ <h2>Say Hello Times: {{ count }}</h2>
  <h2>Essential Links</h2>

script の部分を

Hello.vue/script
<script lang="ts">
  import Vue, { ComponentOptions } from 'vue'
  // Declare the component's type
  interface HelloInterface extends Vue {
    msg: string,
    count: number,
    sayHello(): number
  }
  
  export {
    HelloInterface as interface
  }
  export default {
    data() {
      return {
        msg: 'Welcome to Your Vue.js App',
        count: 0
      }
    },
    methods: {
      sayHello() {
        this.count++;
        return this.count;
      }
    }
    // We need to explicitly annotate the exported options object
    // with the Hello type
  } as ComponentOptions<HelloInterface>;
</script>

こうして改造します

親としての App.vue を改造してみて

App.vue/template
  <div id="app">
-   <img src="./assets/logo.png">
+   <img src="./assets/logo.png" @click="sayHello">
-   <hello></hello>
+   <hello ref="helloComponent"></hello>
  </div>
App.vue/script
<script lang="ts">
  import Vue, { ComponentOptions } from 'vue';
  import { interface as helloInterface, default as Hello } from './components/Hello.vue';
  interface App extends Vue {
    $refs: {
      // helloComponent を宣言する、helloComponent のメソッドとプロパティを使えようになるました
      helloComponent: helloInterface
    }
  }
  export default {
    methods: {
      sayHello() {
        this.$refs.helloComponent.count++;
        this.$refs.helloComponent.sayHello();
      }
    },
    components: {
      Hello
    }
  } as ComponentOptions<App>;
</script>

refsといった動的なもの、interface に宣言して、typescript にオートコンプリートを使えます。

App.vue の scriptlang=ts 変更すると、main.js を main.ts に変更する必要があります、webpack の entry も忘れないでください,そうしないと file not found のエラーが発生する可能性がある。

コードはちょっと多いね、公式サイトによるの vue-class-component を使ってみますか?

vue-class-component

vue-class-componentの demo と readme はちょっと問題があります、TypeScript の新入りの私は困りました。pr を提出したので、速くマージされて欲しいです

vue-class-component を使っている Hello.vue

Hello.vue
<script lang="ts">
  import Vue from 'vue'
  import Component from 'vue-class-component'

  @Component
  export default class Hello extends Vue {
    msg: string = 'Welcome to Your Vue.js App'
    count: number = 0
    sayHello(): number {
      this.count++;
      return this.count;
    }
  }
</script>

で、App.vue

App.vue/script
<script lang="ts">
  import Vue from 'vue'
  import Component from 'vue-class-component'
  import Hello from './components/Hello.vue';
  
  @Component({
    components: {
      Hello
    }
  })
  export default class App extends Vue {
    $refs: {
      helloComponent: Hello
    }
    
    sayHello() {
      this.$refs.helloComponent.count++;
      this.$refs.helloComponent.sayHello();
    }
  }
</script>

随分清潔になりました、オートコンプリートもバッチリ!他の vue コンポーネントと TypeScript の不具合は一時的に考えなかった。

終わりに

Vue 2.5から TypeScript のサポートはどんどん増えると言われています。どんなサポートですかね〜

はじめて日本語に技術相関の文章を作りますから、変なところいっぱいと思います、コメントエリアに指摘すれば幸いです。

最後まで閲覧いただきありがとうございました。

オリジナルリンク:https://blog.xingoxu.com/ja/2017/10/vue-typescript-early/

54
31
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?