2. 指令

2.1. 内置指令

2.1.1. v-bind

v-bind 指令可以用于响应式地更新 HTML attribute。

v-bind 主要用于动态绑定 DOM 元素属性(attribute),即元素属性实际的值是由 vm 实例中的 data 属性提供的。

1
2
3
4
5
	<div id="img">
		<p>v-bind指令</p>
		<img v-bind:src="path" width="200" height="200">
		<img :src="path2" width="200" height="200">
	</div>
1
2
3
4
5
6
7
		var image = new Vue({
			el: '#img',
			data: {
				path: "../img/China.png",
				path2: "../img/USA.png"
			}
		})

2.1.1.1. Class与Style绑定

在开发过程中,我们经常会遇到动态添加类名或直接修改内联样式(例如 tab 切换)。 class 和 style 都是 DOM 元素的 attribute,我们当然可以直接使用 v-bind 对这两个属性进行数据绑定,例如 <p v-bind:style=‘style’><p>,然后通过修改 vm.style 的值对元素样式进行修改。但这样未免过于繁琐而且容易出错,所以 Vue.js 为这两个属性单独做了增强处理,表达式的结果类型除了字符串之外,还可以是对象和数组。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
	<div id="attr-bind">
		<p>Class与Style绑定</p>
		<p>在开发过程中,我们经常会遇到动态添加类名或直接修改内联样式(例如 tab 切换)。</p>
		<div>
			<div class="tab" v-bind:class="{'active':active,'unactive':!active}">
				单个class绑定
			</div>
			<div v-bind:class="[classA,classB]">
				多个class绑定
			</div>
		</div>
	</div>
1
2
3
4
5
6
7
8
		var attr = new Vue({
			el: '#attr-bind',
			data: {
				active: true,
				classA: 'active',
				classB: 'show',
			}
		})

2.1.2. 计算属性

在项目开发中,我们展示的数据往往需要经过一些处理。除了在模板中绑定表达式或者利用过滤器外,Vue.js 还提供了计算属性这种方法,避免在模板中加入过重的业务逻辑,保证模板的结构清晰和可维护性。

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。

<div id="app">
                  <p>{{ firstName }}</p>
                  <p>{{ lastName }}</p>
                  <p>{{ fullName }}</p>
          </div>
          <div id="app-2">
                  <p>&yen;{{price}}</p>
                  <input type="text" v-model="cents" />
          </div>
var vm2=new Vue({
    el:'#app-2',
    data:{
        cents: 100
    },
    computed:{
        price : {
            set : function(newValue){
                this.cents=newValue*100;
            },
            get : function(){
                return (this.cents/100).toFixed(2);
            }
        }
    }
});
var vm = new Vue({
    el: '#app',
    data: {
        firstName: 'Gavin',
        lastName:'CLY'
    },
    computed : {
        fullName : function() {
            // this 指向 vm 实例
            return this.firstName + ' ' + this.lastName
        }
    }
});

2.1.3. v-model

该指令主要用于 input、select、textarea (表单控件) 标签中,具有 lazy、number、debounce(2.0 废除)、trim(2.0 新增)这些修饰符。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
	<div id="compute">
		<p>v-model指令(表单控件)</p>
		<div>
			<p>redio</p>
			<label><input type="radio" name="" id="" value="male" v-model="gender" />man</label>
			<label><input type="radio" name="" id="" value="female" v-model="gender" />female</label>
			<p>{{gender}}</p>
		</div>
		<div>
			<p>checkbox</p>
			<input type="checkbox" name="" id="" value="" v-model="checked" />
			<span>checked: {{checked}}</span>
			<hr>
			<p>multichecked</p>
			<label><input type="checkbox" value="1" v-model="multiChecked">1</lable>
				<label><input type="checkbox" value="2" v-model="multiChecked">2</lable>
					<label><input type="checkbox" value="3" v-model="multiChecked">3</lable>
						<p>MultiChecked: {{ multiChecked.join('|') }}</p>
		</div>
		<div>
			<p>select</p>
			<select v-model="selected">
				<option selected>A</option>
				<option>B</option>
				<option>C</option>
			</select>
			<span>Selected: {{ selected }}</span>
			<p>multi-select</p>
			<select v-model="multiSelected" multiple>
				<option selected>A</option>
				<option>B</option>
				<option>C</option>
			</select>
			<br>
			<span>MultiSelected: {{ multiSelected.join('|') }}</span>
		</div>
	</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
		var compute = new Vue({
			el: '#compute',
			data: {
				text_message: '',
				age: 0,
				gender: '',
				checked: '',
				multiChecked: [],
				selected: '',
				multiSelected: []
			}
		})

Vue.js 为表单控件提供了一些参数,方便处理某些常规操作。

  • lazy : 默认情况下,v-model 在 input 事件中同步输入框值与数据,加 lazy 属性后从会改到在 change 事件中同步。

  • number : 会自动将用户输入转为 Number 类型,如果原值转换结果为 NaN 则返回原值。

  • trim : 新增了 trim 修饰符,去掉输入值首尾空格。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
		<div>
			<p>text</p>
			<input type="text" name="" id="" v-model.lazy="text_message" />
			<span>your input is {{text_message}}</span>
			<br>
			<input type="text" name="" id="" value="" v-model.trim="text_message" />
			<span>your input is {{text_message}}</span>
			<input type="text" name="" id="" value="" v-model.number.lazy="age" />
			<span>your input is {{age}}</span>
		</div>

2.1.4. v-on 事件绑定与监听

v-on 指令,它用于监听 DOM 事件

通过 v-on 可以绑定实例选项属性 methods 中的方法作为事件的处理器,v-on: 后参数接受所有的原生事件名称。

Vue.js 为指令 v-on 提供了多个修饰符,方便我们处理一些 DOM 事件的细节,并且修饰符可以串联使用。主要的修饰符如下。

  • .stop: 等同于调用 event. stopPropagation()。

  • .prevent: 等同于调用 event.preventDefault()。

  • .capture: 使用 capture 模式添加事件监听器。

  • .self: 只当事件是从监听元素本身触发时才触发回调。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
	<div id="event">
		<p>事件绑定与监听</p>
		<div>
			<p>鼠标点击事件</p>
			<button type="button" v-on:click="say">say</button>
			<button type="button" @click="showEvent($event)">changing and logging</button>
			<p>修饰符</p>
			<div v-on:click="saySelf('click from inner')" v-on:click.self="saySelf('click from self')"
				style="background-color: aqua;">
				<button v-on:click="saySelf('button click')">button</button>
				<button v-on:click.stop="saySelf('just button click')">button</button>
			</div>
		</div>
	</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
		var event = new Vue({
			el: '#event',
			data: {
				message: 'hello world!!'
			},
			methods: {
				say: function () {
					alert(this.message)
				},
				showEvent: function (event) {
					this.message = 'I have print some message on console.',
						console.log(event)
				},
				saySelf(message) {
					alert(message)
				}
			}
		})

2.1.5. 条件渲染

v-if/v-else/v-show 这三个指令主要用于根据条件展示对应的模板内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
	<div id="condition">
		<p>条件渲染</p>
		<div v-if="show">
			v-if is true
		</div>
		<div v-else>
			v-if is false
		</div>
		<div v-show="show">
			v-show is true
		</div>
	</div>
1
2
3
4
5
6
		var condition = new Vue({
			el: '#condition',
			data: {
				show: true,
			}
		})

2.1.6. v-for

当包含参数 index 或 key 时,对象参数修改为(item, index)或(value, key),这样与 JS Array 对象的新方法 forEach 和 map,以及一些对象迭代器(例如 lodash)的参数能保持一致。

备注

v-for=“n in 10” 中的 n 由原来的 0 ~ 9 迭代变成 1 ~ 10 迭代。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
	<div id="list">
		<p>列表渲染</p>
		<ul>
			<li v-for="(item,index) in items">
				<h3>{{index}}</h3>
				<h4>{{item.title}}</h4>
				<span>{{item.description}}</span>
			</li>
		</ul>
		<p>n in 10</p>
		<ul>
			<li v-for="n in 10" v-text="n"></li>
		</ul>
	</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
		var for_list = new Vue({
			el: '#list',
			data: {
				items: [{
					title: 'title-1',
					description: 'description-1'
				},
				{
					title: 'title-2',
					description: 'description-2'
				},
				{
					title: 'title-4',
					description: 'description-3'
				},
				{
					title: 'title-3',
					description: 'description-4'
				}
				],
			},
		})

2.1.7. 其他

1
2
3
4
5
6
7
8
9
	<div id="complex">
		<span v-text="message"></span>
		<div v-html="HTML" class="tab"></div>
		<!-- <div v-el:demo>this is a el mode</div> -->
		<div v-pre> v-pre 跳过编译这个元素和子元素 {{message}}</div>
		<div v-cloak> v-cloak 可以隐藏未编译的 Mustache
			标签直到实例准备完毕 {{message}}</div>
		<span v-once>{{message}}</span>
	</div>
1
2
3
4
5
6
7
		var complex = new Vue({
			el: '#complex',
			data: {
				message: 'this is vue instance.',
				HTML: '<p>complex</p>'
			}
		})

2.1.7.1. v-text

v-text,参数类型为 String,作用是更新元素的 textContent。{{}} 文本插值本身也会被编译成 textNode 的一个 v-text 指令。而与直接使用 {{}} 不同的是,v-text 需要绑定在某个元素上,能避免未编译前的闪现问题。

2.1.7.2. v-HTML

v-HTML, 参数类型为 String,作用为更新元素的 innerHTML,接受的字符串不会进行编译等操作,按普通 HTML 处理。

2.1.7.3. v-once

v-once 指令是 Vue.js 2.0 中新增的内置指令,用于标明元素或组件只渲染一次,即使随后发生绑定数据的变化或更新,该元素或组件及包含的子元素都不会再次被编译和渲染。

2.1.7.4. v-pre

v-pre 指令相对简单,就是跳过编译这个元素和子元素,用来减少编译时间。

2.1.7.5. v-cloak

v-cloak 指令相当于在元素上添加了一个 [v-cloak] 的属性,直到关联的实例结束编译。官方推荐可以和 css 规则 [v-cloak]{ display :none } 一起使用,可以隐藏未编译的({{}}) Mustache 标签直到实例准备完毕。

2.2. 自定义指令

2.2.1. 指令的注册

2.2.1.1. 全局注册

可以通过 Vue.directive(id, definition) 方法注册一个全局自定义指令,接收参数 id 和定义对象。

<body>
    <h2>指令的注册</h2>
    <div id="basic">
            <span>全局指令注册</span>
            <div v-if="isExist" v-consloe-show="param"></div>
    </div>
</body>
Vue.directive('consloe-show',{
    bind : function(){
        console.log('bind',arguments)
    },
    update:function(value,oldValue){
        console.log('update',value,oldValue)
    },
    unbind:function(){
        console.log('unbind',arguments)
    }
})
var consloe_show=new Vue({
    el:'#basic',
    data:{
        param:'first',
        isExist:true
    }
})

2.2.1.2. 组件局部注册

也可以通过在组件的 directives 选项注册一个局部的自定义指令。

var comp=Vue.extend({
    directives:{
        'localDirective':{} //
    }
})