我尝试使用v-for和v-model的组合来获取某些输入表单的双向数据绑定。我想动态创建子组件。目前,我没有看到子组件更新父级的数据对象。
我的模板看起来像这样
[
和js这个
<div class="container" id="app">
<div class="row">
Parent Val
{{ ranges }}
</div>
<div class="row">
<button
v-on:click="addRange"
type="button"
class="btn btn-outline-secondary">Add time-range
</button>
</div>
<time-range
v-for="range in ranges"
:box-index="$index"
v-bind:data.sync="range">
</time-range>
</div>
<template id="time-range">
<div class="row">
<input v-model="data" type="text">
</div>
</template>
我也做了一个js小提琴[{3}}
答案 0 :(得分:3)
注意:使用数组会使事情变得复杂:您无法修改别名(v-for变量)。
经常没有提到的一种方法是catch the native input event as it bubbles up to the component。这可能比必须在链中传播Vue事件更简单,只要您知道元素在组件中的某个位置发出本机input
或change
事件即可。我在这个例子中使用change
,因此在离开现场之前你不会看到它。由于数组问题,我必须使用splice
让Vue注意到元素的更改。
Vue.component('time-range', {
template: '#time-range',
props: ['data']
})
new Vue({
el: '#app',
data: {
ranges: [],
},
methods: {
addRange: function () {
this.ranges.push('')
},
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div class="container" id="app">
<div class="row">
Parent Val
{{ ranges }}
</div>
<div class="row">
<button
v-on:click="addRange"
type="button"
class="btn btn-outline-secondary">Add time-range
</button>
</div>
<time-range
v-for="range, index in ranges"
:data="range"
:key="index"
@change.native="(event) => ranges.splice(index, 1, event.target.value)">
</time-range>
</div>
<template id="time-range">
<div class="row">
<input :value="data" type="text">
</div>
</template>
要使用the .sync
modifier,子组件必须发出update:
variablename 事件,父母将捕获并发挥其魔力。在这种情况下, variablename 为data
。您仍然必须使用数组下标表示法,因为您仍然无法修改v-for别名变量,但Vue对数组元素上的.sync
很聪明,因此没有杂乱的splice
。
Vue.component('time-range', {
template: '#time-range',
props: ['data'],
methods: {
emitUpdate(event) {
this.$emit('update:data', event.target.value);
}
}
})
new Vue({
el: '#app',
data: {
ranges: [],
},
methods: {
addRange: function () {
this.ranges.push('')
},
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div class="container" id="app">
<div class="row">
Parent Val
{{ ranges }}
</div>
<div class="row">
<button
v-on:click="addRange"
type="button"
class="btn btn-outline-secondary">Add time-range
</button>
</div>
<time-range
v-for="range, index in ranges"
:data.sync="ranges[index]"
:key="index">
</time-range>
</div>
<template id="time-range">
<div class="row">
<input :value="data" type="text" @change="emitUpdate">
</div>
</template>