<input v-model="sth" />
// 等同于
<input :value="sth" @input="sth = $event.target.value" />
其中,
也就是说, v-model="sth" 是 :value="sth" @input="sth = $event.target.value" 的缩写。
解释:
$event 指代当前触发的事件对象。
$event.target 指代当前触发的事件对象的dom
$event.target.value 就是当前dom的value值
在@input方法中,
value => sth
在:value中:
sth => value
如此,形成了一个闭环,也就是所说的数据的双向绑定。
说明:
这个语法糖必须是固定的,什么意思?
也就是说,满足语法糖规则:属性必须为value,方法名必须为:input。缺一不可。
自定义组件怎么实现v-model
<my-component v-model="price"></my-component>
要实现,自定义组件my-component的v-model,该如何实现。
根据我们上面的语法糖规则,我们可以进行拆解:
// 拆解如下
<my-component :value="price" @input="price = $event.target.value"></my-component>
// 根据这个我们可以在子组件中,进行拼凑value属性,input方法。
Vue.component('my-component', {
template: `
<span>
<input
type="text"
:value="value"
@input="$emit('input', $event.target.value)"
>
</span>
`,
props: ['value'],
})
其中:
首先,跟我们拼凑出来的格式,
- 该组件中肯定是有value属性的,所以有,props:['value'],这个没问题吧,然后我们将传进来的value值,绑定到原生input标签的value属性上。
虽然都是value,但不是一个value,大家不要弄混了。一个是父组件传进来的值,一个是原生input自带的属性。
- 然后这个组件中向外抛出了一个input方法。我们可以通过,$emit方法,向外抛出一个方法,即input方法
在子组件中的$event.target.value方法,跟我们文章开始的解释一样。将原生input中的value属性的值,放入到了我们抛出去的input的参数。
如此,大家发现没?
我们只是一直在伪造,拼凑承语法糖的样子,就可以实现v-model
那么,不是输入框?也就是没有value属性,那怎么实现v-model???
对于,复选框没有value属性,也没有input方法,怎么解决?
<input type="checkbox" :checkd="value" @change="handleChecked"/>
解决方案:
一样的道理,我们仍是需要拼凑出对相应的语法糖格式。
// 得到它,我们就可以实现v-model
<my-component :value="price" @input="price = $event.target.value"></my-component>
template: `
<span>
<input
type="checkbox"
:checked="value"
@change="$emit('input', $event.target.checked)"
>
</span>
`,
props: ['value'],
})
如上:
将传进来的props值value,这次我们绑定给checked。
对于input方法,这次我们在@change中抛出Input方法,参数为,$event.target.checked。记住是checked属性哦~
// 得到了一样的结果
<my-component v-model="price"></my-component>
网友评论