v-model实现
模拟v-model实现数据双向绑定
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <HdInput :value="title" @update:value="change"></HdInput> </div> <hr> {{ title }} </template>
<script> import HdInput from './components/hdInput.vue';
export default { components: { HdInput }, data() { return { title: '测试' } }, methods: { change(val) { this.title = val; } } } </script>
|
子组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div> <input type="text" :value="content" @input="change"> {{ content }} </div> </template>
<script>
export default { props: ['value'], emits: ['update:value'], data() { return { content: this.value } }, methods: { change(event) { this.content = event.target.value;
this.$emit('update:value', this.content); } } }
</script>
|
这样就实现了数据双向绑定的效果。
v-model的实现方式:将父组件内向子组件传递的方法改为v-model,值改为需要监听的变量即可。
1 2 3 4 5
| <template> <div> <HdInput :value="title" v-model:value="title"></HdInput> </div> </template>
|
v-model后面的 :value
是什么意思呢?
其实就是 update方法后面传递的值。比如这里的value修改为 modelValue,那么子组件内部的接受值也需要相对应的修改。修改后与之前的效果一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <!-- 父组件 --> <HdInput :value="title" v-model:modelValue="title"></HdInput>
<!-- 子组件 --> <template> <div> <input type="text" :value="content" @input="change"> {{ content }} </div> </template>
<script>
export default { props: ['modelValue'], emits: ['update:modelValue'], data() { return { content: this.modelValue } }, methods: { change(event) { this.content = event.target.value;
this.$emit('update:value', this.content); } } }
</script>
|
v-model如果删除掉后面的参数值应该怎么处理呢?
很简单,子组件内部直接使用modelValue
即可。
多个v-model
的使用
利用v-model:value 的语法实现同一个组件内多个v-model属性的应用,实现对多个数据的双向绑定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <lesson v-for="item in db" :key="item.id" :lesson="item" class='hd' @del="show" v-model="item.title" v-model:price="item.price"/>
<!-- 子组件 --> <template> <h3 @dblclick="inpurPriceShow = true"> <input v-if="inpurPriceShow" type="text" :value="lesson.price" @input="$emit('update:price', $event.target.value)" @blur="inpurPriceShow = false" @keyup.enter="inpurPriceShow = false"> <strong v-else>{{ lesson.price }}</strong> </h3>
<h3 @dblclick="inpurPriceShow = true"> <input v-if="inpurPriceShow" type="text" :value="lesson.price" @input="$emit('update:price', $event.target.value)" @blur="inpurPriceShow = false" @keyup.enter="inpurPriceShow = false"> <strong v-else>{{ lesson.price }}</strong> </h3> </template>
<script> export default { inheritAttrs: false, props: ['lesson', 'modelValue', 'price'], emits: { 'update:modelValue': null, 'price': null }, data() { return { inputShow: false, inpurPriceShow: false } } } </script>
|
v-model自定义修饰符
v-model内置的修饰符:
名称 |
作用 |
说明 |
trim |
移除用户输入的内容两端的空格 |
不会移除中间的空格 |
lazy |
使表单监听 change 事件而不是 input |
也就是表单数据在发生变化时才会通知去改变响应式数据 |
number |
将输入的合法符串转为数字 |
遇到处理不了的会返回输入值 |
自定义修饰符官方文档参考
组件的 v-model
上所添加的修饰符,可以通过 modelModifiers
prop 在组件内访问到。当然,如果v-model后加上了:value等参数,那么获取自定义修饰符的时候也需要进行相对应的修改,modelModifiers修改为valueModifiers
.
v-model修饰符可以连续使用
使用方法:直接在v-mode后面使用 . 调用即可。
__END__