[vue.js/nuxt.js/ts]Nuxt.js+TS

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>

 

 

 

Leave a Reply