v-model这个语法糖是什么味儿的?

1,890 阅读3分钟

什么是语法糖?

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。------百度百科

简单来说,语法糖就是某种代码的简介写法。

为什么说v-model是v-bind和v-on的语法糖?

vue中,常常会用到v-on,v-bind,v-model这三个指令。v-on绑定一个事件,v-band可以动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。
比如,想要根据接口返回的内容动态的渲染图片,可以写成:

//代码块1:
<img v-bind:src="imageSrc"> 
(或缩写形式:<img :src="imageSrc">)

此时src的值就不再是固定的了,而是会根据imageSrc的值动态获取。

但其实上面的例子并不能完全展示双向绑定这个概念,继续看下面的例子,实现输入框的双向绑定:

//代码块2:
<input type="text" v-bind:value="inputValue" 
v-on:input="inputValue=$event.target.value">
<p>{{inputValue}}</p>

在页面输入框中输入可以发现这段代码利用v-bind和v-on实现了双向绑定。实现的原理是:首先绑定input框的值为inputValue,然后通过input事件监听input框值得改变,当值改变时将input框中的新值赋给绑定的inputValue,从而实现了双向绑定的概念。

但是,用过vue的人都知道,大多数时候,我们并不会用代码块2的方式去实现表单元素的双向绑定,而是会用下面这段代码:

//代码块3
<input type="text" v-model="modelValue">
<p>{{modelValue}}</p>

可以发现,上面这段代码也可以实现input框的双向绑定。代码块3和代码块2实现的效果是一样的,通过vue文档可以了解,v-model可以在表单控件或者组件上创建双向绑定。v-model将代码块2中绑定input框的值和监听@input方法这两步一起做了,因此才会说,v-model是v-band和v-on的语法糖,即,v-model算是v-band和v-on的简洁写法。

不得不说,v-model这个语法糖确实是有点甜啊。

在自定义组件中使用v-model

上面的例子是将表单组件直接写在父组件里,如果将表单组件提取成子组件的话,也可以用v-model:
image.png
image.png
这里有两点值得注意。

  1. 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件;
    比如上面的代码中,如果子组件中props接收的值不为value而使用inputValue,那这里的双向绑定是会有点问题的。(具体可以通过代码验证一下)

2.一般的input输入框可以遵循第一点,但通过测试可以发现单选框、复选框这类的输入控件利用value和input并不能实现双向绑定,那么应该怎么办呢?
vue提供了model选项可以用来避免这样的冲突:
image.png
从vue官方提供的例子可以发现,vue提供了model,通过在model中设置prop和event,来实现不使用默认名为value的prop和名为input事件的情况。(其实这里也可以解决1的问题,有兴趣可以自己试试)

在vue3中使用v-model

上面所介绍的v-model,都是基于vue2来演示的,大体上和在vue3中使用没有什么特别大的区别,但是'在自定义组件中使用v-model'这点上,vue3与vue2有所区别,vue3摒弃了上面所提到的model,而换了一种新的写法,并且还支持多个v-model绑定的情况。
不过,我的项目是vue2,so,使用vue3且有兴趣的可以自己研究一下~ 更多感兴趣的可以看这里:developer.hs.net/thread/1967