見出し画像

Vue.jsのtypescriptで@PropSyncを使う時にハマったので備忘録を書いていきます

そもそも@PropSyncは何をしてくれるのか?と言うところから書いていきます。

そもそも@PropSyncは何をしてくれるのか?

子コンポーネントから親コンポーネントの値を変更する際に、$emitとかを使わずに使えるようになります。

子から親の値を直接変更しようとすると、エラーになりますよね。だからいつも子の方で$emitと親の方で@を使ってイベント検知して変更するようにしていますよね。

その際にもっと省略して実装できるのが@PropSyncです。

今回は例でボタンをクリックすると、名前が変更されるっていうのを見ていきたいと思います。

コードの比較

子(@PropSync使わないver)


<template>
 <div class="button">
   <button @click="nameChange">Myworld</button>
   <p>{{name}}</p>
 </div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'


@Component
export default class Child extends Vue{

    @Prop()
    public name?: string;

 nameChange() {
   const new_name: string = "斉藤"     (stringの指定要らないよ〜ってエラーになるかも)
   this.$emit('change_name', new_name)
 }

 
}
</script>

親(@PropSync使わないver)

<template>
 <div class="about">
   <h1>This is an Country page</h1>
   <child :name="ini_name" @change_name="change_ini_name" />
 </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Child from '@/components/Child.vue'

@Component({
 components: {
   Child
 }
})
export default class About extends Vue {
 public ini_name: string = "松井"       (stringの指定要らないよ〜ってエラーになるかも)

 change_ini_name(new_name: string) {
   this.ini_name = new_name
 }
}
</script>

普通に実装するとこんな感じです。

次は@PropSyncを使った書き方を見ます。

子(@PropSync使うver)

<template>
 <div class="button">
   <button @click="nameChange">Myworld</button>
   <p>{{name}}</p>
 </div>
</template>

<script lang="ts">
import { Component, PropSync, Vue } from 'vue-property-decorator'

@Component
export default class Child extends Vue{
 
 @PropSync('name', { type: String }) name_ele!: string

 nameChange() {
   const new_name: string = "斉藤"     (stringの指定要らないよ〜ってエラーになるかも)
   this.name = new_name            // 変更   
 }
}
</script>

・子から親の値を直接変更できます。

自分なりの理解ですが、@PropSyncの使い方です。公式

@PropSync('バインドされるプロパティ名', { type: 値の型 }) 子コンポーネント内での変数名!: 型
@PropSync('name', { type: String }) name_ele!: string

親(@PropSync使うver)

<template>
 <div class="about">
   <h1>This is an Country page</h1>
   <child :name.sync="ini_name" />     // 変更
 </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Child from '@/components/Child.vue'

@Component({
 components: {
   Child
 }
})
export default class About extends Vue {
 public ini_name: string = "松井"       (stringの指定要らないよ〜ってエラーになるかも)
}
</script>

・change_nameメソッドが必要なくなるので削除します。

.syncを付けるのを忘れなければ、特に問題ないと思います。

2つを比べるとだいぶ省略しているのがわかると思います。@PropSyncの使えばだいぶ楽できるかもしれませんね。

勉強中なので、間違っている事を言っている場合は教えてください

今回はこんな感じで!

以上!