第三章 指令
指令:是特殊的带有前缀v- 的特性。指令的值限定为绑定表达式,指令的职责就是当其表达式的值改变时把某些特殊的行为应用在DOM上
一. 内部指令
.内置指令
1.v-if
根据表达式的值在DOM中生成或移除一个元素。当赋值为false
则对应的元素会从DOM中移除,否则对应元素的一个克隆将被重新插入DOM中。(这也是v-if
和v-show
的一个区别)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-if</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<!--v-if中的内容为true则显示,false则隐藏-->
<p v-if="beautiful"><span>beautiful girl</span></p>
</div>
<script>
new Vue({
el:'#box',
data:{
beautiful:false,
}
})
</script>
</body>
</html>
v-if是一个指令,需要将它添加到一个元素上,但如果想切换多个元素,则可以把元素当做包装元素,并在其上使用v-if,最终的渲染结果不会包含template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-if</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<template v-if="ok">
<h1>happly good day</h1>
<p>chapter01</p>
<p>chapter02</p>
</template>
</div>
<script>
new Vue({
el:'#box',
data:{
ok:true
}
})
</script>
</body>
</html>
2.v-show
根据表达式的值来显示或隐藏HTML元素。当v-show为false
,元素将被隐藏。查看DOM
时会发现元素上多了一个内联样式style="display:none"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-show</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<!--条件为TRUE,输出-->
<h1 v-show="ok">Hello!</h1>
<!--条件为false,不输出-->
<h1 v-show="error">false!</h1>
<!--条件为TRUE,输出-->
<h1 v-show="10>5">10大于5,输出!</h1>
<!-- 条件为false,不输出-->
<h1 v-show="2>10">不大于10,不输出!</h1>
</div>
<script>
new Vue({
el:'#box',
data:{
ok: true,
error: false
}
})
</script>
</body>
</html>
注意:v-show不支持<template>
一般来说,v-if
有更高的切换消耗,而v-show
有更高的初始渲染消耗。因此需要频繁切换,则使用v-show
较好;若在运行时条件不大可能改变则使用v-if
较好。
3.v-else
:使用它必须跟在v-if/v-show
充当else功能。(其实就是在v-if后面和if else条件判断的作用是一样的)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-else</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<h1 v-if="ok">Hello!</h1>
<h1 v-else="ok">false!</h1>
</div>
<script>
new Vue({
el:'#box',
data:{
ok: false,
}
})
</script>
</body>
</html>
4.v-model
指令用来在input、select、text、checkbox、radio
等表单控件上创建双向数据绑定。根据控件类型v-model
自动选取正确的方法更新元素。v-model
是语法糖,在用户输入事件中更新数据,以及特别处理一些极端例子。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-model </title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<form action="">
<label for="name">姓名:</label>
<input type="text" v-model="name" id="name">
<br>
性别:
<input type="radio" id="man" value="One" v-model="sex">
<label for="man">男</label>
<input type="radio" id="male" value="Tow" v-model="sex">
<label for="male">女</label>
<br>
兴趣:
<label for="book">阅读</label>
<input type="checkbox" id="book" value="book" v-model="interest">
<label for="swim">游泳</label>
<input type="checkbox" id="swim" value="swim" v-model="interest">
<label for="game">游戏</label>
<input type="checkbox" id="game" value="game" v-model="interest">
<label for="song">唱歌</label>
<input type="checkbox" id="song" value="song" v-model="interest">
<br>
<label for="identify">身份:</label>
<select name="" id="identify">
<option value="teacher" selected>教师</option>
<option value="doctor">医生</option>
<option value="lawyer">律师</option>
</select>
</form>
</div>
<script>
new Vue({
el:'#box',
data:{
name:'',
sex:'',
interest:[],
identify:''
}
})
</script>
</body>
</html>
v-model指令后面还可以添加多个参数(number、lazy、debounce)<template>
①number
如果想将用户的输入自动转换为Number类型(如果原值的转换结果为NaN,则返回原值),
可以添加一个number特性。
②lazy
在默认情况下,v-model在input事件中同步输入框的值和数据,我们可以添加一个lazy特性,从而将数据改到在change事件中发生。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-model </title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<input type="text" v-model.lazy="msg" >
<br>
{{msg}}
</div>
<script>
new Vue({
el:'#box',
data:{
msg:'内容是在change事件之后才改变的'
}
})
</script>
</body>
</html>
③debounce
设置一个最小的延时,在每次敲击之后延时同步输入框的值和数据。如果 每次更新都要进行高耗操作(如在input中输入内容时随时发送ajax请求)则他较为有用
5.v-for
基于源数据重复渲染元素。我们也可以使用$index
来呈现相对应的数组索引。
这里的写法在vue2.0中不再适用所以不写出来了,学习v-for参考官网列表渲染
vue包装了被观察数组的变异方法,他们能触发视图更新
变异方法 (mutation method):
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
非变异 (non-mutating method) 方法,例如 filter()、concat() 和 slice() 。它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组。
v-for提供的内置过滤器:
Vue.extend
Vue.nextTick
Vue.set
Vue.delete
Vue.directive
Vue.filter
Vue.component
Vue.use
Vue.mixin
Vue.compile
Vue.observable
Vue.version
6.v-text
可以更新元素的textContent
7.v-html
可以更新元素的innerHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-text</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<template>
<div>
<p v-text="hello"></p>
<p v-html="hello"></p>
{{ num }}<br>
{{ status ? 'success' : 'fail' }}
</div>
</template>
</div>
<script>
new Vue({
el:'#box',
data:{
hello: '<span>Hello World</span>',
num: 1,
status: true
}
})
</script>
</body>
</html>
8.v-bind
用于响应更新HTML特性,将一个或多个attribute,或者一个组件prop动态绑定到表达式
v-bind简写为冒号:
<img v-bind:src="" alt="" >
<img :src="" alt="">
在绑定class或style时,支持其他类型的值,如数组或对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-text</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
.A{
font-size: 1.2rem;
color: #fff;
background-color: #cccccc;
}
.classB{
font-weight: bold;
border-bottom: 1px solid #666666;
}
</style>
</head>
<body>
<div id="box">
<p :class="[classA,{classB:isB,classC:isC}]">Hello World</p>
</div>
<script>
new Vue({
el:'#box',
data:{
classA:'A',
isB:true,
isC:false
}
})
</script>
</body>
</html>
没有参数时,可以绑定到一个对象。注意,此时class和style不支持数组和对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-bind</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
#idName{
color: #fff;
background-color: #317ee7;
font-weight: bold;
}
</style>
</head>
<body>
<div id="box">
<div v-bind="{id:someProp,'OTHERAttr':otherProp}">HelloWorld</div>
</div>
<script>
new Vue({
el:'#box',
data:{
someProp:'idName',
otherProp:'prop',
}
})
</script>
</body>
</html>
在绑定prop时,prop必须在子组件中声明。可以用修饰符指定不同的绑定类型。
修饰符为: .sync——双向绑定,只用于prop绑定。
.once——单次绑定,只用于prop绑定。
.camel——将绑定的特性名字转换回驼峰命名。只能用于普通HTML特性的绑定,通常用于绑定用驼峰命名的svg特性。(比如viewBox)
<div id="box">
<div v-bind="{id:someProp,'OTHERAttr':otherProp}">HelloWorld</div>
<!--prop绑定,“prop”必须在m-component组件内声明-->
<my-component :prop="someThing"></my-component>
<!--双向prop绑定-->
<my-component :prop.sync="someThing"></my-component>
<!--单向prop绑定-->
<my-component :prop.once="someThing"></my-component>
</div>
9.v-on
用于绑定事件监听器。事件类型由参数指定;表达式可以是一个方法的名字或者一个内联语句;如果没有修饰符,可以省略。
使用在普通元素上时,只能监听原生DOM事件;使用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
在监听原生DOM事件时,如果只定义一个参数,DOM event
为事件的唯一参数;如果在内联语句处理器中访问原生DOM事件,则可以用特殊变量 $event
把他传入方法。
10.v-ref
在父组件上注册一个子组件的索引,便于直接访问。可以通过父组件的$refs
对象访问子组件。
11.v-el
为DOM元素注册一个索引,方便通过所属实例$refs
访问这个元素。可以用v-el:some-el
设置this.$els.someEl
12.v-pre编译时跳过当前元素和他的子元素。可以用来显示原始Mustache标签。跳过大量没有指令的节点会加快编译。
13.v-cloak
保持在元素上直到关联实例结束编译。
二.自定义指令
1.基础
1-1钩子函数
update
——在bind之后立刻以初始值为参数第一次调用,之后每次绑定值变化时调用,参数为新值与旧值。
unbind
——只调用一次,在指令从元素上解绑时调用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<div v-my-directive="someValue"></div>
</div>
<script>
new Vue({
el:'#box',
data:{
}
})
Vue.directive('my-directive',{
bind:function () {
// 准备工作
},
update:function (newValue,oldValue) {
// 值更新时的工作
// 也会以初始值为参数调用一次
},
unbind:function () {
// 清理工作
}
})
</script>
</body>
</html>
1-2.指令实例属性
所有的钩子函数都将被复制到实际的指令对象中,在钩子内this指向这个指令对象。这个对象暴露了一些有用的属性。
属性:el——指令绑定的元素
vm——拥有该指令的上下文ViewModel
expression——指令的表达式,不包括参数和过滤器
arg——指令的参数
name——指令的名字,不包含前缀
modifiers——一个对象,包含指令的修饰符
descriptor——一个对象,包含指令的解析结果
1-3.对象字面量
如果指令需要多个值,则可以传入一个JavaScript对象字面量。
1-4字面修饰符
1-5元素指令
2.高级选项
params
deep
twoWay
acceptStatement
Terminal
priority
3.内部指令解析
4.常见问题解析