Vue指令详解:从入门到精通
前言
Vue.js作为当下最流行的前端框架之一,其指令系统是Vue最核心的特性之一。指令是Vue模板中带有v-
前缀的特殊属性,它们为HTML元素添加了特殊的响应式行为。本文将全面介绍Vue的各种指令及其用法。
一、Vue指令概述
Vue指令是带有v-
前缀的特殊属性,用于在表达式的值改变时响应式地将某些行为应用到DOM上。
<p v-if="seen">现在你看到我了</p>
二、常用内置指令详解
1. v-bind
动态绑定一个或多个属性,或一个组件prop到表达式。
<!-- 绑定属性 -->
<img v-bind:src="imageSrc"><!-- 缩写 -->
<img :src="imageSrc"><!-- 绑定class -->
<div :class="{ active: isActive }"></div><!-- 绑定style -->
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
2. v-model
在表单控件或组件上创建双向数据绑定。
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
3. v-if / v-else-if / v-else
条件渲染指令,根据表达式的值来有条件地渲染元素。
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else>C</div>
4. v-show
根据表达式之真假值,切换元素的display CSS属性。
<h1 v-show="ok">Hello!</h1>
v-if vs v-show:
- v-if 是"真正"的条件渲染,会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
- v-show 只是简单地切换元素的CSS display属性。
- v-if 有更高的切换开销,而v-show有更高的初始渲染开销。
5. v-for
基于源数据多次渲染元素或模板块。
<!-- 数组 -->
<li v-for="(item, index) in items">{{ index }} - {{ item.message }}
</li><!-- 对象 -->
<li v-for="(value, key, index) in object">{{ index }}. {{ key }}: {{ value }}
</li><!-- 范围 -->
<span v-for="n in 10">{{ n }}</span>
key的作用:
当Vue更新使用v-for渲染的元素列表时,默认使用"就地复用"策略。为了给Vue一个提示以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的key属性。
<div v-for="item in items" :key="item.id"><!-- 内容 -->
</div>
6. v-on
绑定事件监听器。
<!-- 方法处理器 -->
<button v-on:click="doThis"></button><!-- 缩写 -->
<button @click="doThis"></button><!-- 内联语句 -->
<button @click="doThat('hello', $event)"></button><!-- 事件修饰符 -->
<form @submit.prevent="onSubmit"></form>
常用事件修饰符:
- .stop - 调用event.stopPropagation()
- .prevent - 调用event.preventDefault()
- .capture - 添加事件侦听器时使用capture模式
- .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调
- .once - 只触发一次回调
- .passive - 以{ passive: true }模式添加侦听器
7. v-text
更新元素的textContent。
<span v-text="msg"></span>
<!-- 等价于 -->
<span>{{msg}}</span>
8. v-html
更新元素的innerHTML。
<div v-html="htmlContent"></div>
注意:在网站上动态渲染任意HTML非常危险,容易导致XSS攻击。只在可信内容上使用v-html,永不用在用户提交的内容上。
9. v-pre
跳过这个元素和它的子元素的编译过程。
<span v-pre>{{ 这里不会被编译 }}</span>
10. v-cloak
这个指令保持在元素上直到关联实例结束编译。
<div v-cloak>{{ message }}
</div><style>
[v-cloak] {display: none;
}
</style>
11. v-once
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。
<span v-once>这个将不会改变: {{ msg }}</span>
三、自定义指令
除了内置指令,Vue也允许注册自定义指令。
1. 注册全局自定义指令
Vue.directive('focus', {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}
})
2. 注册局部自定义指令
directives: {focus: {inserted: function (el) {el.focus()}}
}
3. 使用自定义指令
<input v-focus>
4. 钩子函数
一个指令定义对象可以提供如下几个钩子函数(均为可选):
- bind:只调用一次,指令第一次绑定到元素时调用。
- inserted:被绑定元素插入父节点时调用。
- update:所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。
- componentUpdated:指令所在组件的VNode及其子VNode全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
5. 钩子函数参数
每个钩子函数都有以下参数:
- el:指令所绑定的元素,可以用来直接操作DOM。
- binding:一个对象,包含以下属性:
- name:指令名,不包括v-前缀。
- value:指令的绑定值。
- oldValue:指令绑定的前一个值。
- expression:字符串形式的指令表达式。
- arg:传给指令的参数。
- modifiers:一个包含修饰符的对象。
- vnode:Vue编译生成的虚拟节点。
- oldVnode:上一个虚拟节点。
四、指令的高级用法
1. 动态指令参数
从2.6.0开始,可以用方括号括起来的JavaScript表达式作为一个指令的参数:
<a v-on:[eventName]="doSomething"> ... </a>
2. 对象语法
从2.6.0开始,可以给指令传递一个对象字面量:
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
五、最佳实践
- 合理使用指令修饰符,简化代码
- 在v-for中总是使用key
- 避免v-if和v-for用在同一元素上
- 谨慎使用v-html,防止XSS攻击
- 对于复杂DOM操作,考虑使用自定义指令封装
结语
Vue指令系统提供了强大的模板操作能力,从简单的数据绑定到复杂的DOM操作,都能通过指令优雅地实现。掌握这些指令的使用方法和适用场景,能够大大提高Vue开发效率和代码质量。
希望本文对你理解和使用Vue指令有所帮助!如果有任何问题,欢迎在评论区留言讨论。