我正在尝试创建一个接受对象作为prop的组件,并且可以使用sync或emit事件修改该对象的不同属性并将值返回给父对象。这个例子不起作用,但它只是为了展示我想要实现的目标。
这是我想要实现的内容的片段:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<p>Parent value: {{parentObject}}</p>
<child v-model="parentObject"></child>
</div>
<template id="child">
<input type="text" v-bind:value.value1="value" v-on:input="updateValue($event.target.value)">
<input type="text" v-bind:value.value2="value" v-on:input="updateValue($event.target.value)">
</template>
&#13;
select (2299) / (((2299) * 20 )/ (100 * 360)) from dual;
&#13;
答案 0 :(得分:4)
您不应该修改作为道具传入的对象。相反,您应该在子组件中创建一个新的数据属性,并使用prop对象的副本对其进行初始化。
然后,我只对子组件中的每个输入使用v-model
,并为内部值添加一个深度观察器,每当内部值发生变化时,它将发出update
。
Vue.component('child', {
template: '#child',
props: ['value'],
data() {
return { val: {...this.value} };
},
watch: {
val: {
deep: true,
handler(value) {
this.$emit('input', value);
}
}
}
});
new Vue({
el: '#app',
data: {
parentObject: {value1: "1st Value", value2: "2nd value"}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="app">
<p>Parent value: {{parentObject}}</p>
<child v-model="parentObject"></child>
</div>
<template id="child">
<div>
<input type="text" v-model="val.value1">
<input type="text" v-model="val.value2">
</div>
</template>
我在我的示例({...this.value}
)中制作了一个浅的副本,因为该对象没有任何嵌套属性。如果不是这种情况,您可能需要进行深层复制(JSON.parse(JSON.stringify(this.value))
)。
答案 1 :(得分:2)
在#app
中,shoudld为parentObject
,而不是parentValue
。
在孩子中,你有两个inpyt
,但你必须有一个根元素。在下面的示例中,我为组件创建了一个<div>
根元素。
要更新父级,请发出事件。这种方法不会修改子项中父项的属性,因此不会破坏单向数据流。
Vue.component('child', {
template: '#child',
//The child has a prop named 'value'. v-model will automatically bind to this prop
props: ['value']
});
new Vue({
el: '#app',
data: {
parentObject: {value1: "1st Value", value2: "2nd value"}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<p>Parent value: {{parentObject}}</p>
<child v-model="parentObject"></child>
</div>
<template id="child">
<div>
<input type="text" v-bind:value="value.value1" v-on:input="$emit('input', {value1: $event.target.value, value2: value.value2})">
<input type="text" v-bind:value="value.value2" v-on:input="$emit('input', {value1: value.value1, value2: $event.target.value})">
</div>
</template>
关于<input>
:您可以将每个绑定到父value
的属性。然后,在编辑时,发出一个事件,仅修改该属性(v-on:input="$emit('input', {value1: $event.target.value, value2: value.value2})
)并保留另一个值。父母因此而更新。
如果您有许多属性,则可以在第二个input
中替换,例如:
$emit('input', {value1: value.value1, value2: $event.target.value})
使用
$emit('input', Object.assign({}, value, {value2: $event.target.value}))
我保留了之前的演示,因为它更直接,更简单(比原始代码更少),但更简洁的方法是使用方法(例如updateValue
)并在模板:
Vue.component('child', {
template: '#child',
//The child has a prop named 'value'. v-model will automatically bind to this prop
props: ['value'],
methods: {
updateValue: function(propertyName, propertyValue) {
this.$emit('input', Object.assign({}, this.value, {[propertyName]: propertyValue}))
}
}
});
new Vue({
el: '#app',
data: {
parentObject: {value1: "1st Value", value2: "2nd value"}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<p>Parent value: {{parentObject}}</p>
<child v-model="parentObject"></child>
</div>
<template id="child">
<div>
<input type="text" v-bind:value="value.value1" v-on:input="updateValue('value1', $event.target.value)">
<input type="text" v-bind:value="value.value2" v-on:input="updateValue('value2', $event.target.value)">
</div>
</template>
如您所见,上面的演示已使用Object.assign()
,这意味着它将处理无限数量的属性。
答案 2 :(得分:0)
<TradeTableItem v-for="(debtReserve, index) in debtReserves" :key="debtReserve.id" :debtReserve="debtReserve" :market="market" :id="'order_by_' + index"></TradeTableItem>
在上一步中,我们为每一行生成了id。
然后在TradeTableItem(您要填充的模板,表格行)中,将id编写为:id =“ this.id”,其中this.id是道具的一部分。
希望这会有所帮助
答案 3 :(得分:0)
不使用props
的另一种方法可能是访问子组件中的组件属性$attrs
。
在父母中
<child v-model="parentObject" />
在子级中,v-model
生成的value属性可以在模板中以以下方式访问
$attrs.value.value1
这是反应性的。
演示HERE