本文全面讲解Vue指令系统,涵盖15+常用指令及其实战应用场景,通过完整案例演示如何高效构建动态Web应用。
一、Vue指令基础概念
Vue指令是带有 v-
前缀的特殊HTML属性,用于赋予DOM元素响应式行为。它们将数据绑定到DOM,实现声明式编程模型。
<!-- 基础用法示例 -->
<div id="app">
<p v-show="isVisible">显示/隐藏内容</p>
</div>
二、核心指令分类精讲
1. 文本渲染指令
指令 | 作用 | 示例 |
---|---|---|
v-text | 渲染纯文本 | <p v-text="content"> |
v-html | 渲染HTML内容(注意XSS风险) | <div v-html="rawHtml"> |
v-once | 单次渲染(后续不更新) | <span v-once>{{ msg }}</span> |
<!-- v-html实际应用 -->
<p>普通渲染: {{ rawHtml }}</p>
<p v-html="rawHtml"></p> <!-- 实际渲染HTML -->
2. 条件渲染指令
<div v-if="score >= 90">优秀</div>
<div v-else-if="score >= 70">良好</div>
<div v-else>继续努力</div>
<div v-show="hasPermission">管理员可见</div>
v-if vs v-show 核心区别:
v-if
:条件为假时完全销毁DOM元素v-show
:始终保留DOM,仅切换CSS的display属性
3. 列表渲染指令(v-for)
<ul>
<!-- 遍历数组 -->
<li v-for="(item, index) in items" :key="item.id">
{{ index + 1 }}. {{ item.name }}
</li>
<!-- 遍历对象 -->
<li v-for="(value, key) in userObj">
{{ key }}: {{ value }}
</li>
</ul>
关键提示:始终使用
:key
绑定唯一标识符,优化虚拟DOM的diff算法性能
4. 事件绑定指令(v-on)
<button @click="submitForm">提交</button> <!-- 简写形式 -->
<input @keyup.enter="search"> <!-- 按键修饰符 -->
<!-- 事件修饰符应用 -->
<div @click.self="parentClick"> <!-- 仅元素自身触发 -->
<button @click.stop="childClick">子元素</button>
</div>
常用事件修饰符:
.stop
:阻止事件冒泡.prevent
:阻止默认行为.self
:仅元素自身触发.once
:事件只触发一次
5. 属性绑定指令(v-bind)
<!-- 简写形式 -->
<div :class="{ active: isActive, 'text-danger': hasError }"></div>
<div :style="{ color: activeColor, fontSize: size + 'px' }"></div>
动态class的三种绑定方式:
// Vue组件中
data() {
return {
// 1. 字符串形式
classString: 'active primary',
// 2. 数组形式
classArray: ['active', { 'text-bold': isBold }],
// 3. 对象形式
classObject: {
active: true,
'text-danger': false
}
}
}
三、双向数据绑定(v-model)
<input v-model="username"> <!-- 基础文本绑定 -->
<textarea v-model="description"></textarea>
<!-- 复选框绑定数组 -->
<input type="checkbox" v-model="hobbies" value="sports"> 运动
<input type="checkbox" v-model="hobbies" value="music"> 音乐
<!-- 单选按钮 -->
<input type="radio" v-model="gender" value="male"> 男
原理说明:v-model本质是语法糖,等价于:
<input :value="text" @input="text = $event.target.value">
四、实战案例:购物车实现
<div id="app">
<button @click="loadCart">刷新购物车</button>
<table>
<thead>
<tr>
<th>商品名称</th>
<th>价格</th>
</tr>
</thead>
<tbody v-if="cartItems.length">
<tr v-for="item in cartItems" :key="item.id">
<td>{{ item.name }}</td>
<td>¥{{ item.price }}</td>
</tr>
</tbody>
<tbody v-else>
<tr>
<td colspan="2">购物车为空</td>
</tr>
</tbody>
</table>
</div>
<script>
new Vue({
el: '#app',
data: {
cartItems: []
},
methods: {
async loadCart() {
// 模拟API请求
this.cartItems = await fetchCartItems();
}
}
})
</script>
五、高级应用:自定义指令
// 全局注册聚焦指令
Vue.directive('focus', {
inserted(el) {
el.focus();
}
})
// 组件内使用
<input v-focus>
自定义指令钩子函数:
bind
:首次绑定元素时调用inserted
:元素插入父节点时调用update
:组件更新时调用(可能发生在子组件更新前)componentUpdated
:组件及子组件更新后unbind
:解绑时调用
六、最佳实践与性能优化
-
避免v-if和v-for同时使用
<!-- 不推荐 --> <div v-for="item in list" v-if="item.active"> <!-- 推荐方案 --> <div v-for="item in activeItems">
computed: { activeItems() { return this.list.filter(item => item.active); } }
-
合理使用事件修饰符提升代码可读性
-
复杂计算使用computed属性避免模板内复杂逻辑
-
大数据量列表使用虚拟滚动