3.1 内置指令
本节主要介绍Vue.js的内置指令。
3.1.1 v-bind
v-bind主要用于动态绑定DOM元素属性(attribute),即元素属性实际的值是由vm实例中的data属性提供的。例如:
<img v-bind:src='avatar' /> new Vue({ data : { avatar : 'http://….' } })
v-bind可以简写为:,上述例子即可简写为<img :src='avatar' />。
v-bind还拥有三种修饰符,分别为.sync、.once、.camel,作用分别如下。
.sync:用于组件props属性,进行双向绑定,即父组件绑定传递给子组件的值,无论在哪个组件中对其进行了修改,其他组件中的这个值也会随之更新。例如:<my-child :parent. sync='parent'></my-child>。父组件实例vm.parent将通过prop选项传递给子组件my-child,即my-child组件构造函数需要定义选项props:['parent'],便可通过子组件自身实例vm.parent获取父组件传递的数据。两个组件都共享这一份数据,不论谁修改了这份数据,组件获取的数据都是一致的。但一般不推荐子组件直接修改父组件数据,这样会导致耦合且组件内的数据不容易维护。
.once:同.synce一样,用于组件props属性,但进行的是单次绑定。和双向绑定正好相反,单次绑定是将绑定数据传递给子组件后,子组件单独维护这份数据,和父组件的数据再无关系,父组件的数据发生变化也不会影响子组件中的数据。例如:<my-child :parent. once='parent'></my-child>
.camel:将绑定的特性名字转回驼峰命名。只能用于普通HTML属性的绑定,通常会用于svg标签下的属性,例如:<svg width='400' height='300' :view-box.camel='viewBox'></svg>,输出结果即为<svg width="400" height="300" viewBox="….."></svg>
不过在Vue.js 2.0中,修饰符.syce和.once均被废弃,规定组件间仅能单向传递,如果子组件需要修改父组件,则必须使用事件机制来进行处理。
3.1.2 v-model
v-model指令在第2.2.3小节中的表单控件中已经说明过了,这里就不再赘述了。该指令主要用于input、select、textarea标签中,具有lazy、number、debounce(2.0废除)、trim(2.0新增)这些修饰符。
3.1.3 v-if/v-else/v-show
v-if/v-else/v-show这三个指令主要用于根据条件展示对应的模板内容,这在第2.3.2小节的渲染语法中也进行了说明。v-if和v-show的主要区别就在于,v-if在条件为false的情况下并不进行模板的编译,而v-show则会在模板编译好之后将元素隐藏掉。v-if的切换消耗要比v-show高,但初始条件为false的情况下,v-if的初始渲染要稍快。
3.1.4 v-for
v-for也是用于模板渲染的指令,在第2.3.3小节列表渲染中我们也已说明过,这里就不再赘述。常见用法如下:
<ul> <li v-for='(index, item) in items'> <p>{{ item.name }}</p> ….. </li> </ul>
v-for指令用法在Vue.js 2.0中做了些细微的调整,大致包含以下几个方面:
1.参数顺序变化
当包含参数index或key时,对象参数修改为(item, index)或(value, key),这样与JS Array对象的新方法forEach和map,以及一些对象迭代器(例如lodash)的参数能保持一致。
2.v-bind:key
属性track-by被v-bind:key代替,<div v-for="item in items" tranck-by="id">需要改写成<div v-for="item in items" v-bind:key="item.id">。
3.n in 10
v-for="n in 10"中的n由原来的0~9迭代变成1~10迭代。
3.1.5 v-on
v-on指令主要用于事件绑定,在第2.4节中我们已经说明。回顾一下用法:
<button v-on:click='onClick'></button>
v-on可以简写为:
<button @click='onClick'></button>
修饰符包括.stop、.prevent、.capture、.self以及指定按键.{keyCode|keyAlias}。
在Vue.js 2.0中,在组件上使用v-on指令只监听自定义事件,即使用$emit触发的事件;如果要监听原生事件,需要使用修饰符.native,例如<my-component v-on:click. native="onClick"></my-component>。
3.1.6 v-text
v-text,参数类型为String,作用是更新元素的textContent。{{}}文本插值本身也会被编译成textNode的一个v-text指令。而与直接使用{{}}不同的是,v-text需要绑定在某个元素上,能避免未编译前的闪现问题。例如:
<span v-text="msg"></span>
如果直接使用<span>{{msg}}</span>,在生命周期beforeCompile期间,此刻msg数据尚未编译至{{msg}}中,用户能看到一瞬间的{{msg}},然后闪现为There is a message,而用v-text的话则不会有这个问题,如图3-1所示。
图3-1
3.1.7 v-HTML
v-HTML,参数类型为String,作用为更新元素的innerHTML,接受的字符串不会进行编译等操作,按普通HTML处理。同v-text类似,{{{}}}插值也会编译为节点的v-HTML指令,v-HTML也需要绑定在某个元素上且能避免编译前闪现问题。例如:
<div>{{{HTML}}}</div> <div v-HTML="HTML"></div>
3.1.8 v-el
v-el指令为DOM元素注册了一个索引,使得我们可以直接访问DOM元素。语法上说,可以通过所属实例的$els属性调用。例如:
<div v-el:demo>there is a el demo</div> vm.$els.demo.innerText // -> there is a el demo
或者在vm内部通过this进行调用。
另外,由于HMTL不区分大小写,在v-el中如果使用了驼峰式命名,系统会自动转成小写。但可以使用“-”来连接你期望大写的字母。例如:
<div v-el:camelCase>There is a camelcase</div> <div v-el:camel-case>There is a camelCase</div> vm.$els.camelcase.innerText // -> There is a camelcase vm.$els.camelCase.innerText // -> There is a camelCase
3.1.9 v-ref
v-ref指令与v-el类似,只不过v-ref作用于子组件上,实例可以通过$refs访问子组件。命名方式也类似,想使用驼峰式命名的话用“-”来做连接。例如:
<message v-ref:title content="title"></message> <message v-ref:sub-title content="subTitle"></message> var Message = Vue.extend({ props : ['content'], template : '<h1>{{content}}</h1>' }); Vue.component('message', Message);
我们最终将vm.$refs.title和vm.$refs.subTitle用console.log的方式打印到控制台中,结果为:
输出了两个子组件的实例。
从理论上来说,我们可以通过父组件对子组件进行任意的操作,但实际上尽量还是会采用props数据绑定,用组件间通信的方式去进行逻辑上的交互,尽量让组件只操作自己内部的数据和状态,如果组件间有通信,也通过调用组件暴露出来的接口进行通信,而不是直接跨组件修改数据。
3.1.10 v-pre
v-pre指令相对简单,就是跳过编译这个元素和子元素,显示原始的{{}}Mustache标签,用来减少编译时间。例如:
<div v-pre>{{ uncompiled}}</div> var vm = new Vue({ el : '#app', data: { uncompiled : 'Thers is an uncompiled element' } });
最后输出:
3.1.11 v-cloak
v-cloak指令相当于在元素上添加了一个[v-cloak]的属性,直到关联的实例结束编译。官方推荐可以和css规则[v-cloak]{ display :none }一起使用,可以隐藏未编译的Mustache标签直到实例准备完毕。例如:
<div v-cloak>{{ msg }}</div>
3.1.12 v-once
v-once指令是Vue.js 2.0中新增的内置指令,用于标明元素或组件只渲染一次,即使随后发生绑定数据的变化或更新,该元素或组件及包含的子元素都不会再次被编译和渲染。这样就相当于我们明确标注了这些元素不需要被更新,所以v-once的作用是最大程度地提升了更新行为中页面的性能,可以略过一些明确不需要变化的步骤。使用方式如下:
<span v-once>{{msg}}</span> <my-component v-once :msg='msg'></my-component>