Yudai Hirano
—Apr 02, 2021
<template><section class="section"><div class="container"><h1 class="title is-size-2">Using Vue's v-model with complex objects</h1><div v-for="(item, i) in holidays" :key="i"><h2 class="is-size-4">{{item.name}}</h2><Child v-model="holidays[i]"/></div>{{JSON.stringify(holidays)}}</div></section></template><script>import Child from "./components/Child";export default {name: "App",components: {Child},data() {return {holidays: [{name: "Fourth Of July",date: null,description: ""},{name: "Thanksgiving",date: null,description: ""}]};}};</script>
<template><div><div class="field"><div class="control"><label for="name" class="label">Name</label><input class="input" :value="value.name" @input="updateValue('name', $event.target.value)"></div></div><div class="field"><div class="control"><label for="date" class="label">Date</label><inputclass="input"type="date":value="value.date"@input="updateValue('date', $event.target.value)"></div></div><div class="field"><div class="control"><label for="textarea" class="label">Textarea</label><textareaclass="textarea":value="value.description"@input="updateValue('description', $event.target.value)"/></div></div></div></template><script>export default {props: {value: {type: Object,required: true}},methods: {updateValue(key, value) {this.$emit("input", { ...this.value, [key]: value });}}};</script>
最も重要な部分は emit イベントの処理です。標準的なinputイベントをemitしたいのですが、今回のvalueは特別なもの(=オブジェクト)になります。
UpdateValueメソッドは、このコード { ...this.value, [key]: value }
によって、新しいオブジェクトの値をemitします。ここでは、コードを非常にきれいに保つために、2つのJavaScriptの機能を使用します。
1つ目は、propを介して渡されたオブジェクトをコピーし、更新されたキー/値をオブジェクトにマージする、**object spread syntax**です。
2つ目は、computed property name を使用することで、変数keyをオブジェクト内のキーの名前として使用することができます。これにより、パラメータとしてキーと値を受け取る汎用のupdateValueメソッドを持つことができ、入力を使ってオブジェクトの正しいキーを更新し、それを親に返すことができます。
https://www.drewtown.dev/post/using-vues-v-model-with-objects/