详解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 相关文章推荐
javascript 函数使用说明
Apr 07 Javascript
jquery下为Event handler传递动态参数的代码
Jan 06 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
Jan 23 Javascript
在js文件中如何获取basePath处理js路径问题
Jul 10 Javascript
Javascript的严格模式strict mode详细介绍
Jun 06 Javascript
Js为表单动态添加节点内容的方法
Feb 10 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
Jun 05 Javascript
JavaSciprt中处理字符串之sup()方法的使用教程
Jun 08 Javascript
值得分享的JavaScript实现图片轮播组件
Nov 21 Javascript
webuploader模态框ueditor显示问题解决方法
Dec 27 Javascript
JavaScript HTML DOM元素 节点操作汇总
Jul 29 Javascript
python实现迭代法求方程组的根过程解析
Nov 25 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笔记之:php数组相关函数的使用
2013/04/26 PHP
php5.3 注意事项说明
2013/07/01 PHP
微信公众平台接口开发入门示例
2014/12/24 PHP
举例讲解PHP面对对象编程的多态
2015/08/12 PHP
php实现的SSO单点登录系统接入功能示例分析
2016/10/12 PHP
PHP共享内存使用与信号控制实例分析
2018/05/09 PHP
PHP实现简单的协程任务调度demo示例
2020/02/01 PHP
CI框架简单分页类用法示例
2020/06/06 PHP
再谈javascript图片预加载技术(详细演示)
2011/03/12 Javascript
Javascript 倒计时源代码.(时.分.秒) 详细注释版
2011/05/09 Javascript
读jQuery之十一 添加事件核心方法
2011/07/31 Javascript
jquery改变disabled的boolean状态的三种方法
2013/12/13 Javascript
AngularJS入门教程之Hello World!
2014/12/06 Javascript
JavaScript运算符小结
2015/06/03 Javascript
Jquery判断form表单数据是否变化
2016/03/30 Javascript
深入剖析JavaScript:Object类型
2016/05/10 Javascript
深入理解Javascript箭头函数中的this
2017/02/13 Javascript
轻松实现jQuery添加删除按钮Click事件
2017/03/13 Javascript
还不懂递归?读完这篇文章保证你会懂
2018/07/29 Javascript
详解关于Angular4 ng-zorro使用过程中遇到的问题
2018/12/05 Javascript
JS数据类型STRING使用实例解析
2019/12/18 Javascript
微信小程序实现自定义底部导航
2020/11/18 Javascript
Vue-router编程式导航的两种实现代码
2021/03/04 Vue.js
对python中使用requests模块参数编码的不同处理方法
2018/05/18 Python
Pycharm设置界面全黑的方法
2018/05/23 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
利用Python实现原创工具的Logo与Help
2018/12/03 Python
Django视图扩展类知识点详解
2019/10/25 Python
基于python实现删除指定文件类型
2020/07/21 Python
英国定做窗帘和纺织品面料一站式商店:Dekoria
2018/08/29 全球购物
法国面料和小百货在线商店:Mondial Tissus
2019/03/23 全球购物
物理力学求职信
2014/02/18 职场文书
对标管理实施方案
2014/03/12 职场文书
JVM之方法返回地址详解
2022/02/28 Java/Android
世界无敌的ICOM IC-R9500宽频接收机
2022/03/25 无线电
详解Flutter自定义应用程序内键盘的实现方法
2022/06/14 Java/Android