Nuxtjsで、プロジェクト作成
npx create-nuxt-app nuxt_ts
インストール
npm i -D @nuxt/typescript
npm i ts-node
npm i -S vue-property-decorator
npm i -S nuxt-property-decorator
js->tsに拡張子変更
nuxt.config.js -> nuxt.config.ts
空のファイルを作成
touch tsconfig.json
実行
cd nuxt_ts
npm run dev
・component作成
components/MyButton.vue
<template> <button>My Button</button> </template> <script lang="ts"> import {Component, Vue} from "vue-property-decorator" @Component export default class MyButton extends Vue{ } </script>
・Page作成
pages/Home.vue
<template> <div> <MyButton></MyButton> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import MyButton from "@/components/MyButton.vue"; @Component({ components: { MyButton, }, }) export default class Home extends Vue {} </script> <style> </style>
@prop @emitプロパティ/バインド・イベント
components/MyButton.vue
<template> <button @click="onClick">{{ title }}</button> </template> <script lang="ts"> import {Component, Prop, Emit, Vue} from "vue-property-decorator" @Component export default class MyButton extends Vue { public title?: string="HELLO"; // ?: 初期化されてない !:初期化されている @Prop() public caption?: string; // バインドしている側にイベント通知 @Emit() public clicked(){ } public onClick(){ //自分のメンバ変数を変更 -> OK this.title = "clicked"; // alert(this.caption); // !!! バインドされたプロパティを変更するとエラー //this.caption = "clicked"; // バインドしている側にイベント通知して、そこで変える。 this.clicked(); } } </script>
pages/Home.vue
<template> <!-- ルートエレメントが1個必要 !!! --> <div> <p>opt: {{opt}}</p> <MyButton v-bind:caption="opt" @clicked='cb_clicked'></MyButton> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import MyButton from "@/components/MyButton.vue"; @Component({ components: { MyButton, }, }) export default class Home extends Vue { public opt: string = "INITIALIZED"; public cb_clicked(){ this.opt = "[CALLBACK]CLICKED"; console.log(this.opt); } } </script> <style> </style>
v-model モデルバインド
アクションごとに、バインドされている変数が変更される。
ResetButton.vue
<template> <button @click="onClick">Reset</button> </template> <script lang="ts"> import {Component, Emit, Prop, Vue} from "vue-property-decorator"; @Component export default class ResetButton extends Vue { @Prop() public initialValue!: string; /** モデルバインドのために記述必須 */ @Prop() public value!: string; /** モデルバインドのために記述必須 */ @Emit() public input(value: string) { } public onClick(){ this.input(this.initialValue); } } </script>
Home.vue
<template> <!-- ルートエレメントが1個必要 !!! --> <div> <p>opt: {{opt}}</p> <!-- プロパティ・イベントをバインド --> <MyButton v-bind:caption="opt" @clicked='cb_clicked'></MyButton> <!-- モデルバインド --> <ResetButton initialValue="Hello" v-model="opt"></ResetButton> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import MyButton from "@/components/MyButton.vue"; import ResetButton from "@/components/ResetButton.vue"; @Component({ components: { MyButton, ResetButton, }, }) export default class Home extends Vue { public opt: string = "INITIALIZED"; public cb_clicked(){ this.opt = "[CALLBACK]CLICKED"; console.log(this.opt); } } </script> <style> </style>
フックルーチン(created)
ResetButton.vue
<template>
<button @click="onClick">Reset</button>
</template>
<script lang="ts">
import {Component, Emit, Prop, Vue} from "vue-property-decorator";
@Component
export default class ResetButton extends Vue {
public initialValue!: string;
@Prop()
public value!: string;
public created(){
console.log("[created]")
this.initialValue = "init value"
}
@Emit()
public input(value: string) {
}
public onClick(){
this.input(this.initialValue);
}
}
</script>
Home.vue
<template> <!-- ルートエレメントが1個必要 !!! --> <div> <p>opt: {{opt}}</p> <!-- プロパティ・イベントをバインド --> <MyButton v-bind:caption="opt" @clicked='cb_clicked'></MyButton> <!-- モデルバインド --> <ResetButton v-model="opt"></ResetButton> </div> </template>
算出プロパティ(vueだと、computed)
<template> <!-- ルートエレメントが1個必要 !!! --> <div> <p>opt: {{opt}}</p> <p>cnt: {{count}}</p> <p v-if="isRegulars">いつもありがとうございます</p> <!-- プロパティ・イベントをバインド --> <MyButton v-bind:caption="opt" @clicked='cb_clicked'></MyButton> <!-- モデルバインド --> <ResetButton v-model="opt"></ResetButton> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import MyButton from "@/components/MyButton.vue"; import ResetButton from "@/components/ResetButton.vue"; @Component({ components: { MyButton, ResetButton, }, }) export default class Home extends Vue { private count: number = 0; public opt: string = "INITIALIZED"; public get isRegulars(): boolean{ return this.count >= 5; } public cb_clicked(){ this.opt = "[CALLBACK]CLICKED"; console.log(this.opt); this.count++; } } </script> <style> </style>
Watch
値変更を監視し、処理を追加する
<script lang="ts"> import { Component, Watch, Vue } from 'vue-property-decorator'; import MyButton from "@/components/MyButton.vue"; import ResetButton from "@/components/ResetButton.vue"; @Component({ components: { MyButton, ResetButton, }, }) export default class Home extends Vue { private count: number = 0; public opt: string = "INITIALIZED"; public get isRegulars(): boolean{ return this.count >= 5; } @Watch('count') public countChanged(){ if(this.count === 5){ alert("count == 5"); } } public cb_clicked(){ this.opt = "[CALLBACK]CLICKED"; console.log(this.opt); this.count++; } } </script>