Vue3 你可能疏忽的 v-model 的巧用
前言:目前曾经应用 Vue3 开发曾经四个多月了,罕用的一些机制本人确信曾经玩的很明确了,然而在这周里看到共事的一个组件设计,用到了 V-model这个机制,给我一种豁然开朗,相见恨晚的感觉,为什么本人之前没早点理解到还能够这样用 …
感觉本人疏忽了 Vue 官网文档的很重要一些常识,于是从新对着官网文档大抵看了一遍。
特来分享一下本人学习到的新的常识。
本文老手向,并不是单纯解说用法,所以我不会间接就开始讲 v-model 的用法,接下来我会把我在我的项目中最实在的思路过程讲述进去,可能附加内容有点多。如果你只想看到 v-model 的用法,请间接跳转到《题目四》
<hr/>
一. 需要背景
- 咱们公司次要我的项目是挪动端开发,应用挪动端框架是 ionic-Vue。做过挪动端开发的应该都晓得,挪动端页面的 Header(手机顶部),Content(内容区域),和Footer 都是十分固定的构造。大抵构造基本上和微信这样的布局构造十分相似。这里类似是指的这三个局部的高度是不会轻易调整的,不然就会造成页面切换的时候页面整体因为高度的变动而造成的“抖动”。用户体验就会变得十分不难受,这是咱们须要防止的状况。
- 周四我在写 UI 提供的一个稿子的时候。简略来说需要就是相似于 QQ 界面的右上角的加号,而后进去一个小弹窗的成果。如下图所示:
二. 实现思路
- 因为这个“加号➕”是位于 Header 局部的,然而显示区域位于 Content 区域。最一开始的想法就是将这个弹窗局部应用 相对定位 来实现,使它和 “加号➕” 位于同一个组件。很遗憾的是,Ionic 所封装的 Header 组件的高度是写死的,如果把这个弹出框写在和
<Ionic-Header>
组件里的话就会呈现如下的成果。上图是我现实达到的成果(这里是为了不便演示,成心超出了一部分)
然而后果却是这样的。因为
<ion-Header>
高度固定,并且设定了 overflow-hidden 属性,那么你的选项框是无奈显示在 Header 局部的。并且其实这个设计思路在最开始就是错的,这个弹出框位于的区域就应该是 Content 区域,而就不应该是位于在 Header 里的。
tips: 在这里想给和我一样的老手开发者说一句,拿到需要切忌马上敲代码而疏忽组件设计思路的思考 - 于是转变了想法,采纳 React 状态晋升的思路。将 Header 和 Content 一起装在了同一个父亲组件里,将弹窗局部写在父组件里,并由父组件来提供扭转状态的办法。
于是我的代码由下图的设计思路:转变为了:
- 这里稍等一下,因为咱们的 header 是一个通用的组件,所以它在理论我的项目中会是一个独自的通用组件的模式,这里咱们把它抽离进来。所以我的项目的构造大略是这样样子的。
- 这里略微调整一下款式,如下所示:(这里解释一下,这里应用的是 tailwindCss 应用本人的语法将款式款式内嵌在 class 属性内,和传统写在 style 里没任何区别)
5. 这时候就很简略了,我设定一个属性值,在点击按钮的时候弹出选项框,再次点击按钮,敞开选项框即可。默认状态下为敞开即可。
三. 应用 Props 的办法
- 接下来就得想方法将这个属性传递给
<Header/>
组件了。非常简单,咱们间接应用 props 即可。而后我还是依照 “React 后遗症 ” 的写法,父组件还须要再提供一个扭转这个属性值的办法。
- 接下来要去子组件承受传递过去的 Props。
- 嗯,看起来性能是失常的。最开始我也是这样想的,然而 leader 说,当初须要点击
<Content/>
区域也能够敞开这个弹出框。我心想,这还不简略啊,我间接给<Content>
也加上这个点击事件不就行了吗?成果如下:
是不是乍一看如同没什么问题,然而我发现如果简略这样的话有个很重大的 BUG,我点击 <Content/>
区域这个选项框也会呈现了。
- 于是我就扭转了
changeShow
这个函数的逻辑。我把它拆分成了两份。 - 同样的,咱们
<Header/>
组件也得接管两个函数。 - 咱们的
<Header>
组件外部也变成了这样子而后把
Content
的点击事件更换为closeOptions
函数,咱们试一下成果。 - 🤔写到这里的时候,我就开始思考,这样尽管能够实现性能。这个场景仅仅是扭转了一个属性值,我就须要传递三个 props 并且这三个属性值仅仅是为了服务一个 boolean 值属性。于是我想到了之前如同看共事开发过一个组件,是应用 v-bind 实现的,于是我转头过来钻研了一下他的代码,随后又去查阅了官网。
四. 通过 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
和设定自定义事件的语法糖。没有什么很特地的中央。然而如果纯熟应用起来的话,在开发通用组件的时候会更近得心应手。