.syncのここが凄い!
コンポーネント間で値を受け渡しする流れが一生分からない。悩んでも仕方ないから、とりあえずインプット量を増やす。てなわけで、今回は.syncに関して学習していく。
.sync修飾子のどこが凄い?
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
この書き方を、以下のようにまとめることができるところ。
:title.sync="doc.title"
.sync修飾子って何?
vueのカスタムイベントの一つ。
親が子に渡した値Aを、子が編集し、編集後の値Aを子から親に返す。
.syncを使うことで、受け取った値Aを親は親は比較的少ない記述量で反映させることができる。
どう使うんですか?
下記のように、v-bindに対して使う。
<text-document
:title.sync="doc.title"
></text-document>
公式Docを見て学習していく。
子は、methodで下記のように記述することで、titleのアップデートを親に送ることができる。
this.$emit('update:title', newTitle)
$emitを使ってnewTitleをupdate:titleに反映させて親に渡している。親は$eventで受け取ることができる。
親は、下記のように$eventを記述することでupdate:titleを取得している。
<text-document
:title="doc.title"
@update:title="doc.title = $event"
></text-document>
このパターンを .sync
修飾子で短く書くことができる。
<text-document
:title.sync="doc.title"
></text-document>
もっと分かりやすい記事ないの?
あります。
参考記事にあった、ユーザーのログインフォームを実装を通して理解を深めてみる。
front/pages/signup.vue
<template>
...
<!-- :name.sync 追加 -->
<user-form-name
:name.sync="params.user.name"
/>
<!-- :email.sync 追加 -->
<user-form-email
:email.sync="params.user.email"
/>
<!-- :password.sync 追加 -->
<user-form-password
:password.sync="params.user.password"
/>
export default {
layout: 'beforeLogin',
data () {
return {
isValid: false,
// 追加
params: { user: { name: '', email: '', password: '' } }
}
}
}
UserNameForm
<user-name-form
:name="params.user.name" # : はv-bindの省略形
@update:name="params.user.name = $event" # @はv-onの省略形
/>
- バインド
:name
で親 → 子へデータを送信し、 - 子でデータを編集。
- 子から編集後のデータを送信し、
- 親は
@update:name
で受け取り、"params.user.name = $event"
で値を代入する。
通常の書き方は上記のようになるが、.sync修飾子を使うと下記のように書くことができる。
<user-name-form
:name.sync="params.user.name"
/>
子⇨親の連動バインディングが.syncで省略されている。
@update:nameで子から編集後のデータを受け取って$eventで親の該当箇所を更新する、という処理が.syncで完結できている。
ちなみに、v-bind は「:」v-onは「@」v-slotは「#」という記述ができる。
front/components/user/userFormName.vue
<template>
<!-- v-model 追加 -->
<v-text-field
v-model="setName"
label="ユーザー名を入力"
placeholder="あなたの表示名"
outlined
/>
</template>
<script>
export default {
props: {
name: {
type: String,
default: ''
}
}
computed: {
setName: {
get () { return this.name },
set (newVal) { return this.$emit('update:name', newVal) }
}
}
}
</script>
- v-modelに入力されたStringの値は、setNameに保存される。
- setNameにはgetterとsetterの二つがある。
- getterを通して、prop(親⇨子の値を受け取ることができるプロパティ )のnameにアクセスすることができる。
- getterで取得したthis.nameは、v-modelに入力された値に更新される。
- 更新された値はnewValとしてsetterに入り、this.$emit('update:name', newVal)によって親に渡される。
まとめ
- .syncを使うことで、子から$emitされた値を親は簡潔な記述で受け取ることができる。
- v-bind は「:」v-onは「@」v-slotは「#」
- propは親⇨子の流れで値が移動する。