オブジェクトをコンポーネントにバインドする時に困ったことがありました。
例えば以下の様な例で考えてみます。
この例ではコンテナ層とプレゼンテーション層でフォームデータをバインドしています。
今回はdataとしてpostFormオブジェクトを定義しており、項目数は2つです。
PostConatainer.vue
<script>
import Post from '../../components/Post/Post.vue'
export default {
components:{
Post,
},
data(){
return {
postForm:{
name: null,
photo: null
}
}
},
render: function(createElement){
return createElement(Post,{
props:{
value: this.postForm
},
on: {
"input" : ($event) => { this.postForm = $event },
},
})
}
}
</script>
propsとして受け取ったPost.vueではフォーム項目をcomputedのプロパティとして定義しています。
でもこれ仮に項目数が100個に増えると、computedの定義も100個にしなければいけないと思いませんか?
Post.vue
<template>
<div class="form">
<el-form ref="form" label-width="120px">
<el-form-item label="名前">
<el-input v-model="name"></el-input>
</el-form-item>
<el-form-item label="写真">
<el-input v-model="photo"></el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props:['value'],
computed:{
name:{
get(){
return this.value.name
},
set(val){
this.$emit('input',{ ...this.value, name: val})
}
},
photo:{
get(){
return this.value.photo
},
set(val){
this.$emit('input',{ ...this.value, photo: val})
}
}
}
}
</script>
```
#解決策
vueのライフサイクルフックであるbeforeCreateでは算出プロパティを定義することができます。
今回$optionsを使用してカスタムプロパティを定義します。
```Post.vue
<template>
<div class="form">
<el-form ref="form" label-width="120px">
<el-form-item label="名前">
<el-input v-model="name"></el-input>
</el-form-item>
<el-form-item label="写真">
<el-input v-model="photo"></el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props:['value'],
methods: {
emitData(val) {
this.$emit('input',{...this.value, ...val});
},
},
beforeCreate() {
[
'name',
'photo'
].forEach((key) => {
this.$options.computed =
{...this.$options.computed,
[key] : {
get() {return this.value[key];},
set(val) {this.emitData({ [key]: val });},
}
}
});
},
}
</style>
```
これで項目数が増えても、キーを足していくだけで追加することができます!。
本当はObject.keysでforEachしたかったですが、beforeCreateの段階ではthis.valueがundefinedとなりました。
これは改善したいので、方法があれば教えて頂きたいです。