.sync修飾子とは
上記をご覧ください。
.sync修飾子を使用すれば複数のフォームで入力した内容を編集したりできる便利。
どうやって使うか
下記のようにモーダルを呼び出すスクリプトを用意しました。
やっていることはボタンを押した際にopenModal(todo)
が発火されtodoオブジェクトをスクリプトに渡しつつモーダルを開くような形にしています。
親コンポーネント
<!-- モーダルを開く際todoObjectを渡す -->
<b-button variant="outline-info" @click="openModal(todo)">
編集
</b-button>
<transition name="modal">
<!-- .syncで子コンポーネントの変更監視 -->
<!-- モーダルを動的にするために子コンポーネントにtodoの情報を渡している -->
<show-modal
:id="todoId"
:timelimit.sync="todoTimelimit"
:content.sync="todoContent"
v-if="showContent"
@close="modalClose"
v-model="editContent"
@edit="editTodo($event)"
/>
</transition>
<script>
export default {
name: 'todo-list',
components: {
ShowModal,
},
// 送られてきたtodoObjectを変数に代入
openModal (todo) {
this.showContent = true
this.todoId = todo.id
this.todoTimelimit = todo.timelimit
this.todoContent = todo.content
},
editTodo (e) {
this.$store.commit('editTodo', {
newContent: this.todoContent,
newTimelimit: this.todoTimelimit,
id: e
})
</script>
続いて子コンポーネントです。
$emitに注目していただけるとわかる通りpropsで受けとっている物の後ろにupdate:
をつけて$emitで渡しています。第二引数は$event
じゃないと親コンポーネントに渡すことができませんでした。
.sync修飾子を利用することでフォームの中に書かれている内容を検知しそれぞれが親のコンポーネントに渡す為、v-modelによって変更感知する必要が無くなります。それにv-modelと違って複数の変更が感知できるようになった為、さらに子コンポーネント内でのフォーム作成の自由度が上がると思います。
子コンポーネント
<template>
<div>
<div class="modal-mask">
<div class="modal-wrapper" @click.self="$emit('close')">
<div class="modal-container">
<div class="modal-header">
編集
</div>
<div class="modal-form">
<b-input-group class="mb-2">
<!-- $emitで入力内容を親コンポーネントに渡している -->
<b-form-input
type="text"
placeholder="やりたいことを入力してください"
@input="$emit('update:content', $event)"
:value="content"
></b-form-input>
<!-- $emitで入力内容を親コンポーネントに渡している -->
<b-form-datepicker
class="mb-2"
placeholder="何日までに行いますか?"
:value="timelimit"
@input="$emit('update:timelimit', $event)"
></b-form-datepicker>
</b-input-group>
</div>
<div class="modal-footer">
<button @click="edit(id)">OK</button>
<button @click="$emit('close')">Close</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'show-modal',
props: ['id', 'timelimit', 'content'] ,
deta () {
return {
closeModal: false,
text: '',
}
},
methods: {
edit(id) {
this.$emit('edit', id)
this.$emit('close')
}
}
}
</script>
最後に.sync修飾子によって送られてきたフォームの内容を下記のスクリプトで送信しています。
<script>
editTodo (e) {
this.$store.commit('editTodo', {
newContent: this.todoContent,
newTimelimit: this.todoTimelimit,
id: e
})
</script>
複数のフォームに対してv-model以外で検知する方法を探していたらsync修飾子というものを見つけました。どん詰まって何時間も浪費するかと思いきや以外とあっさり解決できたのでよかったです。
お役に立てれば幸いです。