非表单组件实现双向绑定的小技巧-- v-model 代替 .sync

简介

一般地,双向绑定多用于表单这类输入组件,但在非表单组件上使用双向绑定的需求也很常见,比如具有单选性质的菜单、标签页等组件,通过双向绑定可以更方便地获取和修改激活项。

之前常用的方法是通过 .sync 修饰符绑定 value 属性,并在组件内部触发 emit('update:value',newValue) 的形式,但还是不够优雅。

最近看 element 源码时发现一个小技巧,value 作为 prop 不变,但触发的自定义事件换成 input,此时就可以通过 v-model 指令代替 .sync 修饰符。

简单说明

v-model 原本是针对表单中输入组件的语法糖,根据输入组件的不同,其内部会触发相应的自定义事件,比如文本框组件就会触发 input 事件。而这里是在非表单组件内部触发 input 事件,也能搭配 v-model 实现双向绑定,说明 v-model 指令被编译成 :value="yourValue" @input=value => yourValue = value" 时,并不需要 100% 判定这是一个表单输入组件,否则的话这里的编译应该是无法通过的。

查看相关源码,发现若是在组件上使用 v-model 指令,编译时确实是直接将其编译为一个名为 value 的 prop 和一个 input 事件。

因此,在非表单输入组件内部使用 input 作为自定义事件,确实是有效的。

当然,还是建议只在绑定简单的数据类型时使用,比如数字、字符串等类型,因为它们很少会有非“整值替换”的变化;复杂的对象还是通过 v-bind + @event 显示声明的方式绑定,因为对象大多只是替换其中的某个属性,甚至是嵌套对象的属性,通过事件自定义修改会更方便。

具体的源码分析可以查看以下链接:
(vue2):https://blog.csdn.net/weixin_43294560/article/details/122585166
(vue3):https://blog.csdn.net/fegus/article/details/125757003

本地查看 v-model 源码:
vue2 中位于 node_modules/vue/dist/vue.js
vue3 应该是 node_modules/vue/dist/vue.global.js

posted @ 2022-10-22 11:10  CJc_3103  阅读(209)  评论(0编辑  收藏  举报