Vue - Vue组件实现v-model的用法
简单说明当我们封装一个组件,比如说MySelect组件,我们希望他的用法是这样的。<my-select v-model="job&amp
·
简单说明
当我们封装一个组件,比如说MySelect
组件,我们希望他的用法是这样的。
<my-select v-model="job">
<my-option value="dev">开发人员</my-option>
<my-option value="test">测试人员</my-option>
<my-option value="manager">管理人员</my-option>
</my-select>
这个用法很普遍,因为Vue本身对表单元素的双向绑定就是这么使用的。但封装这样的组件我遇到最大的问题就是:无法对props中的value进行改变
所以我们需要先了解一下v-model
的实现,下面就详细说一下v-model的实现。
Vue对v-model的实现
如果我们不用v-model来实现双向绑定,那么我们需要这样写:
<template>
<input type="text" v-bind:value="name" @input="inputHandler"/>
<template>
<script>
export default {
data(){
return {
name: ''
}
},
methods: {
inputHandler(value){
if(value == null){
this.name = event.target.value;
}
else{
this.name = value;
}
}
}
}
</script>
- 我们通过vue的
v-bind
指令为input绑定了value,那么在name值发生改变时,input的value也会发生改变。这样就实现了数据驱动DOM
。(至于vue提供的bind是如何实现的,可以去了解一下Object.defineProperties
) - 我们为input绑定了
input事件
,在事件处理函数中将event.target.value
赋值给name。这样就实现了DOM驱动数据
的改变。
基于这两个实现,就实现了DOM和数据的双向绑定。很庆幸Vue对v-model的实现就是这样的(跟官网的描述有些许不同,仅供参考)。可以看出,v-model实际上是通过:value
和@input
来实现的。并且inputHandler
中优先以传入的参数value值给我们绑定的变量赋值,这一点很重要。这使得我们在组件中可以直接通过this.$emit('input', newValue)
来给外界的data属性赋值。
综上所述,我们简单的对my-select组件进行封装
my-select组件的封装(未测试 ?,大概就是这么个逻辑)
<template>
...
</template>
<script>
export default {
props:{
value: String
},
watch:{
// 反向选择:监听value,当value因外界修改发生改变时选中自动选中option
'value': function(newValue){
...
this.selectByValue(newValue);
...
}
},
methods: {
// 选中,点击Option时触发该方法,并传入Option value和Option选中后所显示的内容。
select(value, label){
...
this.$emit('input', value);
...
},
// 根据值来选中Option
selectByValue(value){
// 遍历option,找到value与之对应的option,执行其绑定的click事件处理函数,该函数最终调用了select方法。
}
}
}
</script>
上面的代码粗略的实现了my-select的v-model,简单说明一下:
DOM驱动数据
: 点击Option选项,将Option的value和label(select选中option后显示的内容)作为参数调用select方法,select方法调用this.$emit('input', value)
,这样就实现了DOM驱动数据。数据驱动DOM
:通过watch监听props value,发生改变后调用selectByValue进行选中,这样就实现了数据驱动DOM。
(完)
更多推荐
已为社区贡献3条内容
所有评论(0)