指令是带有 v-
前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
# 数据绑定
# 插值表达式 {{}}
通过 {{}}
可以在页面上插入值或表达式
<p> {{content}} </p>
上面的代码 {{}}
中的 content 属性会被替换为对应的数据,绑定的 content 的值发生变化时此处的值也会随之改变
上面的例子只绑定了简单的变量值。对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。
<p> {{ amount + 1 }} </p>
<p> {{ content == 'vue' ? 'true' : 'false' }} </p>
2
<html>
<body>
<div id="vue-example-1">{{content}}</div>
</body>
<script>
// 创建一个Vue的实例
new Vue({
el: '#vue-example-1', // 当前vue对象将接管上面的div区域
data: {
// 这里绑定值
content: 'hello Vue'
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
v-cloak
在使用插值表达式时,如果网速较慢,则 Vue 实例创建完成前页面会将表达式显示出来,直到实例化完毕后才会被替换为具体的值。我们可以通过 v-cloak
解决这个问题
v-cloak
需要搭配 CSS 来使用,开始时将带有 v-cloak
的标签隐藏,当 Vue 实例化完毕后,页面上的 v-cloak
会被移除,这时内容才会显示出来
<style>
/* 只要是有 v-cloak 属性的标签都让它隐藏。直到 Vue 实例化完毕以后,v-cloak 会自动消失,对应的css样式就会失去作用,最终将内容呈现给用户 */
[v-cloak] {
display: none;
}
</style>
<div id="vue" v-cloak>{{content}}</div>
2
3
4
5
6
7
8
# v-text
v-text
可以将一个变量渲染到指定元素中
<html>
<body>
<div id="vue-example-2" v-text="content"></div>
</body>
<script>
// 创建一个Vue的实例
new Vue({
el: '#vue-example-2', // 当前vue对象将接管上面的div区域
data: {
// 这里绑定值
content: 'hello Vue'
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# v-html
v-html
用法与 v-text
类似,不过 v-html
会把内容解析为 html
, 而 v-text
会将内容作为纯文本
<html>
<body>
<div id="vue-example-3">
<div v-text="content"></div>
<div v-html="content"></div>
</div>
</body>
<script>
new Vue({
el: '#vue-example-3',
data: {
content: '<p style="color: red">hello world</p>'
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意
使用 v-html
渲染数据可能会非常危险,因为它很容易导致 XSS(跨站脚本)攻击,能够使用 {{}}
或者 v-text
实现的不要使用 v-html
# 三种插值方式的比较
{{}}
v-text
和 v-html
都可以在页面中插入值
{{}}
使用方便,一般比较常用,但在网速较慢时可能会出现闪烁的问题,需要搭配 v-cloak
来解决。当你需要在一段固定文本中插入可变的文本,或者插入的数据需要通过单个表达式处理时可以选用此方式
v-text
与 {{}}
相比没有了闪烁的问题,但其替换时会将整个标签内容全部替换,如果标签中原本携带内容则会覆盖,与 {{}}
仅插入数据有所区别
v-html
与 v-text
使用起来相似,不过 v-html
会将数据按照 html
进行解析,一般不要轻易使用
# 属性绑定
# v-bind
v-bind:
能够接收一个参数,用于响应式地更新 HTML attribute。
<img v-bind:src="imageUrl">
上面的例子中 src
为参数, imageUrl
是表达式, v-bind
指令将该元素的 src
属性与表达式 imageUrl
的值绑定。
v-bind
同样支持绑定合法的 js 表达式
<img v-bind:src="'https://www.image.com/' + imageName">
简写 v-bind
通常我们可以省略 v-bind
只写 :
来简写。
例如 <img v-bind:src="imageUrl">
可以简写为 <img :src="imageUrl">
<html>
<div id="vue-example-4">
<!-- 此处没有使用绑定, content 本身是值 -->
<input type="text" value="content">
<!-- 此处使用绑定, value 的值变为表达式, content 是 Vue 实例的变量 -->
<input type="text" :value="content">
</div>
<script>
new Vue({
el: '#vue-example-4',
data: {
content: 'hello Vue'
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 动态参数2.6.0 新增
从 2.6.0 开始,可以用方括号括起来的 JavaScript
表达式作为一个指令的参数
<a v-bind:[attributeName]="url"> ... </a>
这里的 attributeName
会被作为一个 JavaScript
表达式进行动态求值,求得的值将会作为最终的参数来使用。例如当 attributeName
值为 href
时等价于绑定 v-bind:href
# 样式绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组
# style
绑定
我们可以通过 v-bind
来为元素设置 style 行内样式
通过原始行内样式的方式给 <p>
标签设置字体颜色与大小
<html>
<p style="color: red;font-size: 20px">hello Vue</p>
</html>
2
3
<div id="vue">
<p :style="{'color': 'red', 'font-size': '20px'}">hello Vue</p>
</div>
2
3
我们可以将行内样式对象定义到 Vue 实例中,然后引用到 style 中来设置样式对象
<body>
<div id="vue">
<p :style="style">hello Vue</p>
</div>
</body>
<script>
new Vue({
el: '#vue',
data: {
style : {'color': 'red', 'font-size': '20px'}
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
我们可以通过绑定样式数组来设置多个样式对象
<body>
<div id="vue">
<p :style="[style1, style2]">hello Vue</p>
</div>
</body>
<script>
new Vue({
el: '#vue',
data: {
style1 : {'color': 'red', 'font-size': '20px'},
style2 : {'font-style': 'italic'}
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# class
绑定
我们还可以通过 v-bind
来为元素设置 class 类样式
<head>
<title>Title</title>
<style>
.style1 {
color: red;
font-size: 20px;
}
.style2 {
font-style: italic;
}
</style>
</head>
<body>
<p class="style1 style2">hello Vue</p>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
通过 class 的方式给 <p>
标签设置类样式
<head>
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<style>
.style1 {
color: red;
font-size: 20px;
}
.style2 {
font-style: italic;
}
</style>
</head>
<body>
<div id="vue">
<p :class="['style1', 'style2']">hello Vue</p>
</div>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
通过传递数组的方式设置类样式,这里的 class 需要使用 v-bind
进行绑定
注意
上面的代码中 style1 与 style2 在数组中是字符串样式,如果去掉单引号则会变成 Vue 实例的变量不再是样式了
<body>
<div id="vue">
<p :class="[flag ? 'style1' : 'style2']">hello Vue</p>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
flag: true
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在数组中使用三元表达式可以通过 Vue 实例中的变量 flag 来控制样式的显示,当 flag 为 true 时使用 style1 否则使用 style2
我们可以通过参数来控制样式是否使用,下面的例子中通过 flag1
与 flag2
控制使用 style1
<div id="vue">
<p :class="{'style1': flag1, 'style2': flag2}">hello Vue</p>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
flag1: true,
flag2: false
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
我们还可以将样式对象放到 Vue 实例中来直接引用
<div id="vue">
<p :class="style">hello Vue</p>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
style: {'style1': true, 'style2': false}
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
自动添加前缀
当 v-bind:style
使用需要添加浏览器引擎前缀的 CSS property 时,如 transform
,Vue.js 会自动侦测并添加相应的前缀。
# 表单绑定
# v-model
你可以用 v-model
指令在表单 input
、 textarea
及 select
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素
# 绑定文本
<html>
<div id="vue-example-5">
<input type="text" v-model="content">
<p>单行文本输入内容:{{content}}</p>
<textarea v-model="message"></textarea>
<p>多行文本输入内容:{{message}}</p>
</div>
<script>
new Vue({
el: '#vue-example-5',
data: {
content: "hello Vue",
message: "hello Vue"
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 绑定复选框
<html>
<div id="vue-example-6">
<p>单个复选框绑定布尔值:</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{checked}}</label>
<p>多个复选框绑定到数组:</p>
<input type="checkbox" id="a" value="A" v-model="select">
<label for="a">A</label>
<input type="checkbox" id="b" value="B" v-model="select">
<label for="b">B</label>
<input type="checkbox" id="c" value="C" v-model="select">
<label for="c">C</label>
<p>当前选中的字母:{{select}}</p>
</div>
<script>
new Vue({
el: '#vue-example-6',
data: {
checked: true,
select: ["B"]
}
});
</script>
</html>
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
# 绑定单选按钮
<html>
<div id="vue-example-7">
<input type="radio" id="a" value="A" v-model="select">
<label for="a">A</label>
<input type="radio" id="b" value="B" v-model="select">
<label for="b">B</label>
<input type="radio" id="c" value="C" v-model="select">
<label for="c">C</label>
<p>当前选中的字母:{{select}}</p>
</div>
<script>
new Vue({
el: '#vue-example-7',
data: {
select: "B"
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 绑定选择框
<html>
<div id="vue-example-8">
<p>单选选择框</p>
<select v-model="select">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>当前选中的字母: {{select}}</span>
<p>多选选择框</p>
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>当前选中的字母: {{selected}}</span>
</div>
<script>
new Vue({
el: '#vue-example-8',
data: {
select: "",
selected: []
}
});
</script>
</html>
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
# 事件绑定
# v-on
v-on
可以将事件与 Vue 实例中 methods
对象中的方法进行绑定,常见的有
- 绑定点击事件
v-on:click
- 绑定键盘事件
v-on:keydown
v-on:keyup
... - 绑定鼠标事件
v-on:mousedown
v-on:mouseover
... - 绑定表单提交
v-on:submit
- ...
简写 v-on
通常我们可以用 @
来代替 v-on:
完成简写。例如
<button v-on:click="alert">button</button>
可以简写为
<button @click="alert">button</button>
<html>
<div id="vue-example-9">
<button @click="alert">点击弹窗</button>
</div>
<script>
new Vue({
el: '#vue-example-9',
methods: {
alert: function () {
alert("hello Vue")
}
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
调用方法时我们还可以传递参数
<html>
<div id="vue-example-10">
<button @click="alert('hello Vue')">点击弹窗</button>
</div>
<script>
new Vue({
el: '#vue-example-10',
methods: {
alert: function (message) {
alert(message)
}
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event
把它传入方法
<body>
<div id="vue">
<button @click="alert('hello Vue', $event)">button</button>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
methods: {
alert: function (message, event) {
alert(message)
}
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 事件修饰符
修饰符是以半角句号 .
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。 v-on
有很多修饰符来实现一些特殊的功能,常见的修饰符有下面几种
修饰符 | 作用 |
---|---|
.stop | 阻止冒泡 |
.prevent | 阻止组件的默认行为 |
.capture | 事件监听改用捕获的方式而不是冒泡 |
.self | 当事件在该元素本身触发时,才会触发回调 |
.once | 事件只触发一次 |
.{keyCode | keyAlias} | 当事件是从侦听器绑定的元素本身触发时,才触发回调 |
.native | 监听组件根元素的原生事件 |
使用示例 <button @click.stop="doSome"></button>
一个事件可以使用多个修饰符来修饰 <button @click.stop.prevent="doThis"></button>
更多用法举例:
由于事件的冒泡机制,当我们触发一个子标签的事件时,其父标签的事件也会被触发。当我们给子标签事件添加 .stop
修饰后冒泡将不再进行
<div class="father" @click="fatherClick">
<div class="child" @click="childClick"></div>
</div>
2
3
此时点击 child 区域后 childClick 和 fatherClick 事件会被依次触发
<div class="father" @click="fatherClick">
<div class="child" @click.stop="childClick"></div>
</div>
2
3
此时点击 child 区域后只有 childClick 会触发
.capture
可以将事件的触发由冒泡方式改为捕获方式, .capture
需要修饰要捕获的父标签方法
<div class="father" @click="fatherClick">
<div class="child" @click="childClick"></div>
</div>
2
3
此时点击 child 区域后 childClick 和 fatherClick 事件会被依次触发
<div class="father" @click.capture="fatherClick">
<div class="child" @click="childClick"></div>
</div>
2
3
此时点击 child 区域后 会先触发 fatherClick 然后触发 childClick 事件
有些标签自带默认行为,如超链接 <a>
被点击后会跳转到对应的页面,添加 .prevent
可以阻止标签的默认行为
<a href="https://www.baidu.com" @click="customAction">点击跳转</a>
此时点击超链接会执行 customAction 方法同时会跳转到百度页面
<a href="https://www.baidu.com" @click.prevent="customAction">点击跳转</a>
此时点击超链接会执行 customAction 方法并且不会跳转到百度页面
<form action="https://www.baidu.com">
<input type="submit" value="提交">
</form>
2
3
这是一个 form 表单,当点击提交时,表单中的数据会被提交到 action 指定的页面,这是表单的默认行为
<form @submit.prevent action="https://www.baidu.com">
<input type="submit" @click="mySubmit" value="提交">
</form>
2
3
给表单添加 @submit.prevent
会阻止表单的默认提交行为,此时点击提交会执行我们自己的提交方法 mySubmit
由于事件的冒泡机制,当我们触发一个子标签的事件时,其父标签的事件也会被触发。当我们给父标签的事件设置 .self
修饰后,父标签的事件将不会在冒泡中被触发,只有点击了父标签本身其事件才会被触发。
<div class="father" @click="fatherClick">
<div class="child" @click="childClick"></div>
</div>
2
3
此时点击 child 区域后 childClick 和 fatherClick 事件会被依次触发
<div class="father" @click.self="fatherClick">
<div class="child" @click="childClick"></div>
</div>
2
3
此时点击 child 区域后只有 childClick 会触发,fatherClick 不再触发,只有点击 father 区域后才会被触发
注意
.self
只会阻止自己不被冒泡触发,与 .stop
会停止冒泡不同,没有被 .self
修饰的标签正常触发冒泡流程,看上去就像事件冒泡跳过了被 .self
修饰的标签一样
# 按键修饰符
v-on
在监听键盘事件时可以添加按键修饰符,添加按键修饰符后只有触发指定的按键才会触发事件
如 keyup
是键盘抬起时的监听事件, .enter
是 enter 键的按键修饰符, @keyup.enter
就是监听按 enter 键后的事件
<input type="text" @keyup="add">
上面的代码每次按压按键时都会调用绑定的 add 方法
<input type="text" @keyup.enter="add">
上面的代码只有按压 enter 键后才会调用绑定的 add 方法
Vue 中内置的按键修饰符
.enter
.tab
.delete
(捕获 “删除” 和 “退格” 键)
.esc
.space
.up
.down
.left
.right
Vue 1.0.8+ 支持单字母的按键别名
除了内置的按键修饰符,如果我们需要修饰其他按键比如 F5,这时需要使用键盘码 (常用按键键盘码)
例如 F5 的键盘码为 116,则当我们需要按 F5 执行方法时需这样写
<input type="text" @keyup.116="add">
为了方便记忆,Vue 允许我们自定义键盘码修饰符,例如可以这样定义 F5 的键盘码修饰符
<script>
Vue.config.keyCodes.f5 = 116;
</script>
2
3
定义完后我们就可以这样使用
<input type="text" @keyup.f5="add">
2.1.0 新增修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta
在 Mac 系统键盘上, meta
对应 command 键 (⌘)。在 Windows 系统键盘 meta
对应 Windows 徽标键
<!-- Ctrl + C -->
<input @keyup.ctrl.67="copy">
2
2.2.0 新增修饰符处理特定的鼠标按钮
.left
.right
.middle
2.5.0 新增 .exact
修饰符来精确控制修饰符组合
<!-- 只要按住 ctrl 点击就会触发,即使同时按下了如 Alt 键 -->
<button v-on:click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onClick">A</button>
2
3
4
# 列表渲染
# v-for
v-for
可以遍历数组数据,根据指定的模板生成内容,常用于生成列表
<html>
<div id="vue-example-11">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el: '#vue-example-11',
data: {
list: [1, 2, 3, 4]
}
});
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
v-for
遍历各种数据的方式
v-for
可以直接遍历 Vue 实例中的数组内容
<li v-for="item in list">{{item}}</li>
v-for
在遍历数组时可以通过下面的方式同时获得数据的序号
<li v-for="(item, index) in list">{{index}} - {{item}}</li>
当数组中的数据是对象时可以通过下面的方式遍历
<body>
<div id="vue">
<ul>
<li v-for="(item, index) in list">{{item.name}} - {{item.age}}</li>
</ul>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
list: [{name: 'a', age: 10},{name: 'b', age: 11}]
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
v-for
可以直接遍历对象
<body>
<div id="vue">
<ul>
<li v-for="(value, key) in model">{{key}} - {{value}}</li>
</ul>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
model: {name: 'a', age: 10, gender: 'man'}
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
在遍历对象的时候也可以同时获得序号
<li v-for="(value, key, index) in object">{{index}} - {{key}} - {{value}}</li>
v-for
可以直接遍历数字,使用 v-for
遍历数字时起始从 1 开始
<li v-for="index in 5">{{index}}</li>
注意
在 Vue 2.2.0+ 版本使用 v-for
时必须要加上 key 属性,每次 for 循环的时候,通过指定 key 来标示当前循环这一项的唯一身份。
当 Vue.js 用 v-for
更新已渲染过的元素列表时默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue 不是移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。为了让 Vue 能跟踪每个节点的身份,从而重用和重新排序现有元素,需要为每项提供一个唯一 key 属性,key 的类型只能是 string 或 number,而且要通过 v-bind 来指定。
<body>
<div id="vue">
<ul>
<li v-for="(item, index) in list" :key="item.id">{{item.name}} - {{item.age}}</li>
</ul>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
list: [{id: '1', name: 'a', age: 10},{id:'2', name: 'b', age: 11}]
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
如果要遍历的列表数据项会发生变动如增加、删除、重排序等,一定要添加 key 属性来防止列表显示混乱
# 条件渲染
# v-if
v-if
可以根据表达式的真假来决定是否渲染元素,当值为真时渲染,值为假时不渲染。 v-if
在切换时,目标元素及其绑定的数据会被销毁并重建
// isShow 为 true 时 显示
<div v-if="isShow">hello Vue</div>
2
我们可以用 v-else
指令来增加 else
块
<div v-if="isShow">hello Vue</div>
<div v-else>hello world</div>
2
在 Vue 2.1.0 增加 v-else-if
<div v-if="number > 90">A</div>
<div v-else-if="number > 60">B</div>
<div v-else>C</div>
2
3
v-else
必须紧跟 v-if
或 v-if-else
后面否则不被识别
# v-show
v-show
可以根据表达式的真假来控制元素的 display 属性,如果为 false,则在元素上添加 display:none 属性,否则移除 display:none 属性
<body>
<div id="vue">
<div v-show="isShow">hello Vue</div>
</div>
</body>
<script>
var myVue = new Vue({
el: '#vue',
data: {
isShow: true
}
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# v-if
与 v-show
的比较
v-if
与 v-show
都可以用来控制元素的隐藏与显示
v-if
在切换时会添加或移除 dom 元素,所以切换时有性能损耗。
v-show
在切换时不会添加或移除 dom 元素,仅仅控制 display 属性来控制元素的显示隐藏,因此切换时性能损耗很小,但有较高的初始渲染损耗,这是因为开始时如果 v-show
的值是 false,元素依然会被创建只不过被隐藏了而已,但如果初始 v-if
的值为 false 则该元素不会被创建。
因此如果要控制的元素会被频繁的隐藏显示则推荐使用 v-show
,如果要控制的元素开始时并不显示并且后续显示的几率也很小 (比如页面上的错误提示) 则可以使用 v-if
。
# 自定义指令
除了使用 Vue 的系统指令外,Vue 还提供了自定义指令的方法
# 自定义全局指令
我们可以使用 Vue.directive()
来自定义全局指令
例如我们如果要定义一个名为 custom 的指令可以这样实现
<script>
Vue.directive('custom', {
bind: function (el) { ... },
inserted: function (el) { ... },
updated: function (el) { ... }
})
</script>
<!-- 在 div 中使用示例 -->
<div v-custom>自定义指令</div>
2
3
4
5
6
7
8
9
10
可以看到 Vue.directive()
中有两个参数,第一个参数是要定义的指令的名称,在使用时就跟系统指令一样在名称前加上 v-
,例如上面的指令在使用时就需要写 v-custom
第二个参数是一个对象,其中有一些指令相关的钩子函数,这些函数可以在特定的阶段执行相关操作,每个函数的第一个参数一定为 el,若需要添加参数则应该在 el 之后添加,这个 el 参数是一个原生的 JS 对象(DOM 对象),表示被绑定了指令的那个元素,例如上面的例子中最后 el 表示的是 <div>
对象,通过 el 可以对这个 <div>
标签进行操作
bind 函数: 每当指令绑定到元素上的时候会立即执行这个 bind 函数,该函数只执行一次
inserted 函数: 当元素插入到 DOM 中的时候会执行 inserted 函数,该函数只执行一次,与 js 有关的操作最好放到该函数中,防止 js 不生效
updated 函数: 当 VNode 更新的时候会执行 updated 函数,该函数可能会触发多次
如果我们的自定义指令需要传入参数,则可以在钩子函数中添加参数来接收
<script>
Vue.directive('custom', {
bind: function (el, param) { ... },
inserted: function (el, param) { ... },
updated: function (el, param) { ... }
})
</script>
<!-- 在 div 中使用示例 -->
<div v-custom = "'hello Vue'">自定义指令</div>
2
3
4
5
6
7
8
9
10
上面的例子中我们给自定义指令传入了 hello Vue 字符串,钩子函数可以通过 param.value
方式获取该值
简写全局指令
如果你想在 bind 与 updated 时触发相同的行为而不需要其他的钩子函数,那么我们可以简写为下面的形式
<script>
Vue.directive('custom', function (el, param) {
// 这个 function 等同于把代码写到了 bind 和 update 中去
...
})
</script>
2
3
4
5
6
全局指令示例
<body>
<input type="text" id="search" v-focus>
</body>
<script>
Vue.directive('focus', {
bind: function (el) {
},
inserted: function (el) {
el.focus()
},
updated: function (el) {
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
当 <input>
显示到页面后会自动获取焦点
<body>
<input type="text" id="search" v-color="'red'">
</body>
<script>
Vue.directive('color', function (el, param) {
el.style.color = param.value
})
</script>
2
3
4
5
6
7
8
9
将 <input>
的文本设置为红色
注意
v-color="'red'"
里面写的 red 是字符串常量,如果去掉单引号,就成了变量
# 自定义私有指令
在某一个 Vue 对象内部自定义的指令称之为私有指令,这种指令只有在当前 Vue 对象的 el 指定的监管区域有用。
将设置颜色样式的例子改为私有指令
<body>
<div id="app">
<input type="text" id="search" v-color="'red'">
</div>
</body>
<script>
new Vue({
el: '#app',
//自定义私有指令
directives: {
'color': {
bind: function (el, param) {
el.style.color = param.value;
}
}
}
})
</script>
```
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id="app">
<input type="text" id="search" v-color="'red'">
</div>
</body>
<script>
new Vue({
el: '#app',
directives: {
'color': function (el, param) {
el.style.color = param.value;
}
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16