Edited at

Vue + TypeScript 早期体験

More than 1 year has passed since last update.


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/