<input v-model="something">是我们常用的双向绑定方法,如果在自定义组件中如何使用v-model进行双向绑定呢?
首先我们必须要清除v-model绑定的原理如下:
其实v-model的语法糖是这样包装而成的:
<input :value="something" @:input="something = $event.target.value">
而一个组件上使用时则会简化成这样子:
<custom-input :value="something" @input="value => { something = value }"> </custom-input>
因此,对于一个带有 v-model
的组件(核心用法),它应该如下:
- 带有v-model的父组件通过绑定的value值(即v-model的绑定值)传给子组件,子组件通过 prop接收一个 value;
- 子组件利用 $emit 触发
input
事件,并传入新值value给父组件;
this.$emit('input', value);
废话不多说了,直接上栗子;
HTML:
<div id="app"> <my-component v-model="msg"></my-component> msg: {{msg}} <my-counter v-model="num"></my-counter> num: {{num}} </div>
JS:
Vue.component('my-component', { template: `<div> <input type="text" :value="currentValue" @input="handleInput"/> </div>`, data: function () { return { currentValue: this.value //将prop属性绑定到data属性上,以便修改prop属性(Vue不允许直接修改prop属性的值) } }, props: ['value'], //接收一个 value prop methods: { handleInput(event) { var value = event.target.value; this.$emit('input', value); //触发 input 事件,并传入新值 } } }); Vue.component("my-counter", { template: `<div> <h1>{{value}}</h1> <button @click="plus">+</button> <button @click="minu">-</button> </div>`, props: { value: Number //接收一个 value prop }, data: function() { return { val: this.value } }, methods: { plus() { this.val = this.val + 1 this.$emit('input', this.val) //触发 input 事件,并传入新值 }, minu() { if(this.val>0){ this.val = this.val-1 this.$emit('input', this.val) //触发 input 事件,并传入新值 } } } }); new Vue({ el: '#app', data: { msg: 'hello world', num: 0 } })
Demo截图:
注意:
1.带有v-model绑定的父组件下的子组件不一定是要input标签的元素,其他元素都可以;
2.将prop属性绑定到data属性上,以便修改prop属性(Vue不允许直接修改prop属性的值);
3.实现双向绑定是watch监听属性是一个不做的方法(实时监视值的变化);(详细用法)