详解vue中v-model和v-bind绑定数据的异同


Posted in Javascript onAugust 10, 2020

vue的模板采用DOM模板,也就是说它的模板可以当做DOM节点运行,在浏览器下不报错,绑定数据有三种方式,一种是插值,也就是{{name}}的形式,一种是v-bind,还有一种是v-model。{{name}}的形式比较好理解,就是以文本的形式和实例data中对应的属性进行绑定。比如:

var app = new Vue({
 el: '#app',
 template: '<div @click="toggleName">{{name}}</div>',
 data: {
 name: 'tom',
 },
 method: {
 toggleName() {
 this.name = this.name === 'tom' ? 'sony' : 'tom'
 },
 },
})

上面的字符串模板中,有一个{{name}},它和data.name是绑定的,当data.name发生变化时,视图也发生变化。

但是v-bindv-model这两种绑定比较难区分,特别是在表单元素中,刚开始会混淆到底应该怎么使用。

v-bind

首先来看下v-bind,它的用法是后面加冒号,跟上html元素的attributions,例如:

<p v-bind:class="classed">

这里的v-bind:class会产生什么效果呢?实际上,首先你可以看下如果不加v-bind:,也就是:<p class="classed">,这只是一个普通的p元素,含有一个.classed的类,没有任何数据参与进来。

当加上v-bind:之后,就不一样了。它的值classed不是字符串,而是vue实例对应的data.classed的这个变量。也就是说data.classed是什么值,它就会给class属性传递什么值,当data.classed发生变化的时候,class属性也发生变化,这非常适合用在通过css来实现动画效果的场合。除了class,其他大部分html原始的属性都可以通过这种方式来绑定,而且为了方便,它可以直接缩写成冒号形式,例如:

var app = Vue({
 el: '#app',
 template: '<img :src="src">',
 data: {
 src: '',
 },
 beforeMount() {
 fetch(...).then(...).then(res => this.src = res.src) // 这里修改了data.src
 },
})

上面这段代码中,默认情况下data.src是空字符串,也就说不会有图片显示出来,但是当从远端获取到图片地址之后,更新了data.src,图片就会显示出来了。

v-model

v-model主要是用在表单元素中,它实现了双向绑定。双向绑定大家都非常熟了,简单的说就是默认情况下,它跟上面两种情况的数据绑定是一样的,实例的data.name发生变化的时候,对应的试图中也会发生变化。但是v-model绑定后,它还会反过来,在input中手动输入新的内容,会反过来修改data.name的值,如果在视图中其他地方使用到了data.name,那么这个地方就会因为data.name的变化而变化,从而实现关联动态效果。下面来举个栗子:

var app = Vue({
 el: '#app',
 template: '<label><input v-model="name">{{name}}</label>',
 data: {
 name: '',
 },
})

上面<input>中绑定了name,那么当input的value发生变化时,data.name就会跟着发生变化,而data.name变化了{{name}}的地方也会跟着变化。

v-model是一种双向绑定,那么也就是说,你绑定的元素得有机会改变值。所以实际上v-model基本上只会用在input, textarea, select这些表单元素上。

v-bind和v-model混用

有一些情况我们需要v-bind和v-model一起使用。这个时候如果不留神,就会搞乱状况,分不清哪里应该怎么控制。举个栗子:

<input :value="name" v-model="body">

上面就是一个栗子。data.name和data.body,到底谁跟着谁变呢?甚至,它们会不会产生冲突呢?

实际上它们的关系和上面的阐述是一样的,v-bind产生的效果不含有双向绑定,所以:value的效果就是让input的value属性值等于data.name的值,而v-model的效果是使input和data.body建立双向绑定,因此首先data.body的值会给input的value属性,其次,当input中输入的值发生变化的时候,data.body还会跟着改变。

现在的问题是,当这两个一起使用的时候,谁都优先级高?谁会无效?实验证明,v-model将会被使用,v-bind这个时候无效了,因为它正好绑定在value属性上,如果绑在其他属性上v-bind是不受影响的。在这种情况下,v-bind失效,即使你修改data.name,input里面不会有任何变化。

这也说明,v-model建立的双向绑定对输入型元素input, textarea, select等具有优先权,会强制实行双向绑定,如果你愿意的话。
这说明,在单独的input中,同时使用v-bind和v-model是没有必要的,虽然不会造成冲突。

注意上面我说道“单独”,也就是说,在一组输入中,它们又要另当别论。一组输入包括单选组、复选组、下拉选项、下拉选项组。

<label for="value in options">
 <input type="checkbox" :value="value" v-model="selected">
</label>

在data中,它们是这样的:

data: {
 options: [1, 2, 3, 4, 5],
 selected: [],
}

一组复选框,或者一组下拉选项组,也就是select mutiple="true"的情况,它们的结果是一个数组,而非单个值,因此data.selected是一个数组,当一个选项被选中之后,这个选项的value值会被加入到data.selected中(不是按options里面的顺序,而是操作过程中的逻辑)。这个时候:value就是有效的,因为它表示把options数组中对应的选项值传递给value,并不是双向绑定的意思,而只是传值过去(当然,当options中对应的值发生变化时,value值也会变化)。相当于说,v-bind负责value的值,v-model负责选中状态。当然,v-model是双向绑定,界面上你去勾选会影响data.selected的值,你在程序中操作了data.selected,也会反过来影响界面。v-model影响的是勾选效果,而v-bind影响的是值。(实际上,v-bind虽然只是影响值,但是也会影响勾选效果,比如本来一个选框是被勾选的,通过v-bind绑定值发生了变化,那么新来的值就不会在data.selected中,这个选项就不会被勾选。如果没有被勾选,改变后的值又在data.selected中,那又会被勾选上。)

注意,只有当type="checkbox"是确定的情况下,才会让上述情况生效,type值不能是动态值,因为v-model被多次绑定同一个变量时,需要去检查type值,而如果这个时候type是动态的,比如用:type="type"进行动态绑定,就会导致模板编译报错。

v-model其实是v-bind和v-on的语法糖

这是vue官方文档中特别指出的,在阅读到这一句之前,我还对此很模糊,当阅读到:

<input v-model="something">其实是<input v-bind:value="something" v-on:input="something = $event.target.value">的语法糖
时,这种认识上的模糊就被消除了。

我们这篇文章没有讲到v-on,它其实就是一个事件绑定器。我们仔细阅读一下<input v-bind:value="something" v-on:input="something = $event.target.value">,发现它由两部分组成:v-bind:valuev-on:input,必须是value属性和input事件,否则也不会等价于v-model,而且input事件里面,正好是something等于当前输入值。

真因为这一原理,v-model瞬间就不再难理解了。

小结

总之,要区分v-bind和v-model,只需要记住三句话:

1. v-bind是数据绑定,没有双向绑定效果,但不一定在表单元素上使用,任何有效元素上都可以使用;
2. v-model是双向绑定,基本上只用在表单元素上;
3. 当v-bind和v-model同时用在一个元素上时,它们各自的作用没变,但v-model优先级更高,而且需区分这个元素是单个的还是一组出现的。

到此这篇关于详解vue中v-model和v-bind绑定数据的异同的文章就介绍到这了,更多相关vue中v-model和v-bind绑定数据内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquery的ajax简单结构示例代码
Feb 17 Javascript
javascript中返回顶部按钮的实现
May 05 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
Dec 25 Javascript
Jquery zTree 树控件异步加载操作
Feb 25 Javascript
详解angularjs popup-table 弹出框表格指令
Sep 20 Javascript
bootstrap+jquery项目引入文件报错的解决方法
Jan 22 jQuery
小程序云开发教程如何使用云函数实现点赞功能
May 18 Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 Javascript
微信小程序自定义波浪组件使用方法详解
Sep 21 Javascript
vue中使用element ui的弹窗与echarts之间的问题详解
Oct 25 Javascript
Vue实现导航栏菜单
Aug 19 Javascript
js中复选框的取值及赋值示例详解
Oct 18 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
Aug 10 #Javascript
React实现阿里云OSS上传文件的示例
Aug 10 #Javascript
vue+elementUI(el-upload)图片压缩,默认同比例压缩操作
Aug 10 #Javascript
使用vue引入maptalks地图及聚合效果的实现
Aug 10 #Javascript
vue-video-player实现实时视频播放方式(监控设备-rtmp流)
Aug 10 #Javascript
解决vue+webpack项目接口跨域出现的问题
Aug 10 #Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
Aug 10 #Javascript
You might like
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
Yii2.0框架模型多表关联查询示例
2019/07/18 PHP
javascript prototype原型操作笔记
2009/12/07 Javascript
菜鸟javascript基础资料整理3 正则
2010/12/06 Javascript
Javascript中正则表达式的全局匹配模式分析
2011/04/26 Javascript
jquery ajax 同步异步的执行 return值不能取得的解决方案
2012/01/08 Javascript
jquery的相对父元素和相对文档定位示例代码
2013/08/02 Javascript
利用JavaScript检测CPU使用率自己写的
2014/03/22 Javascript
jquery带动画效果幻灯片特效代码
2015/08/27 Javascript
js鼠标点击图片切换效果实现代码
2015/11/19 Javascript
利用Vue.js指令实现全选功能
2016/09/08 Javascript
详解vue 配合vue-resource调用接口获取数据
2017/06/22 Javascript
Javascript读写cookie的实例源码
2019/03/16 Javascript
bootstrap Table实现合并相同行
2019/07/19 Javascript
基于JavaScript实现猜数字游戏代码实例
2020/07/30 Javascript
[01:07:20]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第二场 2月2日
2021/03/11 DOTA
python简单实现旋转图片的方法
2015/05/30 Python
ubuntu系统下 python链接mysql数据库的方法
2017/01/09 Python
Python中工作日类库Busines Holiday的介绍与使用
2017/07/06 Python
用python 批量更改图像尺寸到统一大小的方法
2018/03/31 Python
Python笔记之代理模式
2019/11/20 Python
jupyter notebook运行命令显示[*](解决办法)
2020/05/18 Python
python实现简单遗传算法
2020/09/18 Python
YesStyle美国/全球:购买亚洲时装、美容化妆品和生活百货
2017/01/16 全球购物
打印机墨盒:123Inkjets
2017/02/16 全球购物
美国社交购物市场:MassGenie
2019/02/18 全球购物
机械制造专业毕业生求职信
2014/03/02 职场文书
啤酒节策划方案
2014/05/28 职场文书
党的群众路线对照检查材料范文
2014/09/24 职场文书
幼儿园教师师德表现自我评价
2015/03/05 职场文书
2015年先进个人自荐书
2015/03/24 职场文书
2015年幼儿园保育员工作总结
2015/04/23 职场文书
2015年学校精神文明工作总结
2015/05/27 职场文书
MySQL的安装与配置详细教程
2021/06/26 MySQL
2022微信温控新功能上线
2022/05/09 数码科技
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
2022/05/30 NodeJs