🤔写到这里的时候,我就开始思考,这样虽然可以实现功能。这个场景仅仅是改变了一个属性值,我就需要传递三个 props 并且这三个属性值仅仅是为了服务一个 boolean 值属性。于是我想到了之前好像看同事开发过一个组件,是使用 v-model 完成的,于是我转头过去研究了一下他的代码,随后又去查阅了官网。
四. 通过 v-model 实现
我们先看官网的简介。
说实话,我使用 Vue 几个月以来,一直想不起来使用这个 v-model 的主要原因是就是因为 Vue 官方的这句话
仅限这几个标签去使用,我是真的没看到这个没有高亮效果的 components,所以一开始我也没理解这个 v-model 的真正强大之处。
v-model 的真正用法应该点击这里进入去查阅。
这里我们需要重点去理解这段话的意思:
看到 v-model 展开的样子你发现了什么?对没错,就是一个普普通通的 porps 和一个 emit 自定义事件而已。
(这里官网写的不是特别清楚,导致我最开始没看懂 modelValue 是啥意思。这里的意思应该是,如果你不给 v-model 起一个名字,那么它就会给你起一个默认的名字,叫做 modelValue,对应的,因为它仅仅是一个 props ,所以子组件去也是需要提前定义一个名叫 modelValue 的 props, 子组件才能接收使用)
我们简单验证一下,我在子组件的 props 名称改一下,随之 Vue 就会提示你错误。
如果想要改名字,也非常简单,只需要在 v-model
加一个冒号然后后面跟上名字即可。
搞明白了这个,那么接下来的这个自定义时间也就非常好理解了。
首先父组件注册了一个自定义事件就叫做update:modelValue
,这里需要注意的是 update:
冒号后面跟着的名字和 modelValue
是保持一致的。但是前缀一定有 update:
这个关键单词。举个例子,如果是下面的写法:
那么它最终会被展开写成
再举个极端的例子,这下应该可以明白了吧。如下:
我发现还有人不太明白官方的这个写法, 其实这不就是一个普通的箭头函数吗...
喜欢你可以自己写一个函数放这里也可以呀~
(Tips:但是要记住,你重新声明的这个 @update:isShow=theFunc
会把默认的(newValue)=>isShow=newValue
顶替掉, v-model 仅仅就是上面的一个简写而已。只不过如果你重新设定了这个自定义事件的话,就和你自己传递一个 props 然后传递一个自定义事件没区别了,你就失去了使用 v-model 的意义了,你想使用 v-model 的目的不就是就是想简化一下代码吗)
重点: 父组件注册好了 update:isShow
这个自定义事件,那么现在就剩子组件传递信息过来了。非常简单,在子组件中 emit
即可。
这里使用的是 Vue3 的写法,主要是 Ts
的语法,其实和你直接这样写是一样的const emit=defineEmits(['update:isShow'])
效果和上面通过 props 传递两个改变状态的方法是一模一样的。
五. 总结
v-model 双向绑定其实就是一个看作传递 props
和设定自定义事件的语法糖。没有什么很特别的地方。但是如果熟练使用起来的话,在开发通用组件的时候会更近得心应手。