时间:2021-05-25
一、v-bind 初探
它是一个 vue 指令,用于绑定 html 属性,如下:
<div id="app"> <p v-bind:title="title">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p></div>......var vm = new Vue({ el: '#app', data: { title: 'title content' }});这里的 html 最后会渲染成:
<div id="app"> <p title="title content">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p></div>二、指令预期值
上面这种 v-bind 这也是我们对于 vue 指令最初的理解,但实际上,vue 指令的预期值(如 v-bind:class="classProperty" 中,v-bind 是指令,: 后面的 class 是参数,而 classProperty 则在官方文档中被称为“预期值”),除了像上面那样绑定一个字符串类型变量,其实它是支持一个单一 JavaScript 表达式 (v-for 除外)。
所以在这里,我们就可以有更多的选择,例如:
(1)执行运算
<div id="app"> <p v-bind:title="t1 + ' ' + t2">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p></div>......var vm = new Vue({ el: '#app', data: { t1: 'title1', t2: 'title2' }});最后渲染的结果:
<div id="app"> <p title="title1 title2">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p></div>(2)执行函数等
<div id="app"> <p v-bind:title="getTitle()">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p></div>......var vm = new Vue({ el: '#app', data: { getTitle: function () { return 'title content'; } }});最后渲染的结果:
<div id="app"> <p title="title content">html属性不能使用双大括号形式绑定,只能使用v-bind指令</p></div>三、支持的数据类型
上面的内容,指令预期值得到的都是字符串类型的数据,但实际上,我们知道 js 有很多数据类型,它如果放入其中呢?
(1)对象类型
<div id="app"> <p v-bind:title="obj">content</p></div>......var obj = {};var vm = new Vue({ el: '#app', data: { obj: obj }});为什么一来就选择对象类型呢?答案是它比较有代表性,它渲染结果如下:
<div id="app"> <p title="[object Object]">content</p></div>诶,这个怎么有点眼熟?有点像...没错!对象的 toString 方法的返回值!为了验证我们的猜想,我们进行进一步的测试:
<div id="app"> <p v-bind:title="obj">content</p></div>......var obj = {};obj.toString = function () { return 'edited in toString!';};var vm = new Vue({ el: '#app', data: { obj: obj }});上面这里修改了 obj 的 toString 方法(但准确的说,这里不是修改,而是添加。一开始的 obj 对象上自身是没有 toString 方法的,它继承了 Object.prototype.toString,但这里我们执行 obj.toString = function..... 实际上是为它添加了一个 toString 方法,使得它执行的时候,不用再去调用继承自 Object 的方法),渲染结果如下:
<div id="app"> <p title="edited in toString!">content</p></div>这里就进一步证实了我们的猜想。
(2)数组类型
数组类型的 toString 方法和对象类型的有所不同,它将返回和执行 arr.join(',') 相同的结果。如 [1, 2, 3].toString() 将返回 “1,2,3”。下面进行测试:
<div id="app"> <p v-bind:title="arr">content</p></div>......var vm = new Vue({ el: '#app', data: { arr: [1, 2, 3] }});渲染结果如下:
<div id="app"> <p title="1,2,3">content</p></div>仍然跟预期结果一样。
(3)其它类型
显然,在执行 toString 方法之前,vue 内部应该先做了类型校验,满足条件才输出。而且这里不是简单的真 / 假值校验,因为 、0 虽为假值,但最终却像真值一样渲染了出来。具体如何实现,可能需要参考 vue 的源码了,这里不再深究。
四、多 html 属性值绑定
一个的 html 属性值,可能包含许多内容,需要我们进行一些操作,将多个数据绑定到一个属性上,这里我们可以考虑像前面一样,通过如 “+” 等运算符号等实现字符串的连接操作。但是事实上,字符串连接麻烦又易错,不易于维护。于是我们可以考虑像前面一样向指令预期值中存入一个对象或数组,来实现多个数据绑定到一个属性上的作用。
(1)利用对象绑定
<div id="app"> <p v-bind:title="obj">content</p></div>......var obj = { name: 'Dale', age: 22};// 利用 for-in 循环遍历对象属性,拼接成字符串obj.toString = function () { var str = ''; for(var i in this) { str += i + ': ' + this[i] + '; '; } return str;};// 防止 toString 方法自身被遍历出来Object.defineProperty(obj, 'toString', {'enumerable': false});var vm = new Vue({ el: '#app', data: { obj: obj }});输出结果:
<div id="app"> <p title="name: Dale; age: 22; ">content</p></div>上面通过 for-in 循环在 toString 方法中得到所有可遍历的属性以及对应的属性值,然后将其拼接成字符串再进行输出,可以实现多属性值绑定,至于如何拼接,可以自己在 toString 方法中进行不同的实现 。
(2)利用数组绑定
<div id="app"> <p v-bind:title="arr">content</p></div>......var arr = [1, 2, 3];arr.toString = function () { return this.join(' ');};var vm = new Vue({ el: '#app', data: { arr: arr }});渲染结果如下:
<div id="app"> <p title="1 2 3">content</p></div>相比于对象字符串拼接,数组的拼接操作则显得简单得多,可以直接在 toString 方法返回 join 方法的返回值,默认的 toString 方法的返回值其实就和 join(',') 的返回值相同。
(3)思考
其实想想一个 html 属性绑定多个值的情况其实并不少见,最典型的应该是 class 和 style 属性,或者说我们经常都会接触到这样的场景。
但我们这里的实现,看起来还是问题比较多,数组的绑定还好,对象的绑定,除了每次要重写 toString 方法以外,我们还需要设置 toString 方法变得不可枚举,否则它将在 for-in 循环中被遍历出来(一般情况下,这不是我们希望看到的结果),这样无疑会增加很多重复性工作,而 vue 为我们考虑到了这一点,它在框架内部进行了一些优化操作。
五、vue 对于 class 和 style 绑定的增强
基于上面的情况,vue 对 class 和 style 这两个 html 属性进行了一定程度的增强。vue 具体的实现方式请参考其源码,这里仅给出基于上面的结论的实现方式。
(1)基于对象针对 class 的增强
<div id="app"> <p v-bind:class="obj">content</p></div>......var obj = { c1: true, c2: false, c3: null, c4: undefined};obj.toString = function () { var str = ''; for(var i in this) { if(this[i]) { str += i + ' '; } } return str;};// 防止 toString 方法自身被遍历出来Object.defineProperty(obj, 'toString', {'enumerable': false});var vm = new Vue({ el: '#app', data: { obj: obj }});渲染结果:
<div id="app"> <p class="c1">content</p></div>同样是 for-in,与之前不同的是,当检测到 obj 的某个属性值为真的时候,则将这个属性的属性名添加到绑定的元素的 class 上。当然,我这里只是一个模拟实现,vue 实际的实现方式,请参考 vue 源码。
(2)基于数组对 class 的增强
<div id="app"> <p v-bind:class="arr">content</p></div>.......var arr = ['c1', 'c2', 'c3'];arr.toString = function () { return this.join(' ');};var vm = new Vue({ el: '#app', data: { arr: arr }});渲染结果:
<div id="app"> <p class="c1 c2 c3">content</p></div>这里基本和前面的实现思路一样,利用 join(' ') 实现。
(3)基于对象对 style 的增强
<div id="app"> <p v-bind:style="obj">content</p></div>......var obj = { color: 'red', backgroundColor: '#ddd', fontSize: '20px',};obj.toString = function () { var str = ''; for(var i in this) { if(this[i]) { str += i + ':' + this[i] + ';'; } } return str;};// 防止 toString 方法自身被遍历出来Object.defineProperty(obj, 'toString', {'enumerable': false});var vm = new Vue({ el: '#app', data: { obj: obj }});渲染结果:
<div id="app"> <p style="color: red; background-color: rgb(221, 221, 221); font-size: 20px;">content</p></div>这里基本和前面的实现思路一样,利用 for-in 配合字符串拼接实现。
(4)基于数组对 style 的增强
<div id="app"> <p v-bind:style="arr">content</p></div><script>var arr = [{ color: "red" }, { backgroundColor: '#ddd' }, { fontSize: '20px' }];arr.toString = function () { var str = ''; arr.forEach(function (val, key) { for(var i in val) { str += i + ':' + val[i] + ';'; } });};var vm = new Vue({ el: '#app', data: { arr: arr }});渲染结果:
<div id="app"> <p style="color: red; background-color: rgb(221, 221, 221); font-size: 20px;">content</p></div>这里通过 forEach 方法遍历了数组,然后将数组元素(也就是这里我们的样式对象)再通过 for-in 遍历并拼接成样式字符串达到效果。
六、结语
再次强调,这里只是个人的理解和思考,仅供参考,vue 本身的实现方式未必相同。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
前言在Vue.js版本:1.0.27,使用Vue.js中V-bind指令来绑定class和style时,Vue.js对其进行了增强。表达式结果出了字符串之外,还
过滤器1.过滤器规则Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值{{}}和v-bind表达式(后者从2.1
一、过滤器介绍Vue.js允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind表达式(后者从2.1.0+开始支持
Vue.js允许自定义过滤器,一般可以用在两个地方:双花括号插值和v-bind表达式(后者从2.1.0+开始支持)。过滤器应该被添加在JavaScript表达式
引子v-bind主要用于属性绑定,Vue官方提供了一个简写方式:bind,例如:一、概述v-bind主要用于属性绑定,比方你的class属性,style属性,v