我想在 Vue.js 2.3 中对表单输入进行双向数据绑定。但是,我不能使用该v-model指令,因为我希望仅在单击提交按钮时更新数据。同时,输入值可能是从另一个 Vue 方法更新的,因此应该绑定到 data 属性text。我编写了这样的jsFiddle:
<div id="demo">
<input :value="text" ref="input">
<button @click="update">OK</button>
<p id="result">{{text}}</p>
</div>
Run Code Online (Sandbox Code Playgroud)
new Vue({
el: '#demo',
data: function() {
return {
text: ''
};
},
methods: {
update: function () {
this.text = this.$refs.input.value;
}
}
});
Run Code Online (Sandbox Code Playgroud)
它有效,但当有更多输入时它不能很好地扩展。有没有更简单的方法来实现这一点,而不使用 $refs?
您可以使用对象并将其属性绑定到输入。然后,在您的update方法中,您可以将属性复制到另一个对象以用于显示目的。然后,您可以设置深度观察程序,以便在该对象发生更改时更新输入的值。复制属性时需要使用this.$set,以便将更改注册到 Vue。
new Vue({
el: '#demo',
data: function() {
return {
inputVals: {
text: '',
number: 0
},
displayVals: {}
};
},
methods: {
update() {
this.copyObject(this.displayVals, this.inputVals);
},
copyObject(toSet, toGet) {
Object.keys(toGet).forEach((key) => {
this.$set(toSet, key, toGet[key]);
});
}
},
watch: {
displayVals: {
deep: true,
handler() {
this.copyObject(this.inputVals, this.displayVals);
}
}
}
})Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="demo">
<input v-model="inputVals.text">
<input v-model="inputVals.number">
<button @click="update">OK</button>
<input v-for="val, key in displayVals" v-model="displayVals[key]">
</div>Run Code Online (Sandbox Code Playgroud)
如果您使用的是 ES2015,则可以直接复制对象,因此这并不那么冗长:
new Vue({
el: '#demo',
data() {
return {
inputVals: { text: '', number: 0 },
displayVals: {}
};
},
methods: {
update() {
this.displayVals = {...this.inputVals};
},
},
watch: {
displayVals: {
deep: true,
handler() {
this.inputVals = {...this.displayVals};
}
}
}
})Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="demo">
<input v-model="inputVals.text">
<input v-model="inputVals.number">
<button @click="update">OK</button>
<input v-for="val, key in displayVals" v-model="displayVals[key]">
</div>Run Code Online (Sandbox Code Playgroud)