Vue.js 提供了一系列内置指令(Directives),用于在模板中以声明式的方式操作 DOM 或绑定数据。以下是 Vue 2 和 Vue 3 中常用的核心指令分类及说明:
一、核心指令(Vue 2 & Vue 3 通用)
1、 数据绑定指令
-
v-text
更新元素的 textContent(会覆盖原有内容) -
v-html
动态渲染 HTML(需注意 XSS 风险) -
v-model
双向数据绑定(表单输入、组件通信)
2、条件渲染指令
-
v-if / v-else-if / v-else
条件性渲染元素(DOM 元素会被创建/销毁)Welcome!Please log in. -
v-show
通过 CSS display 控制显示/隐藏(DOM 元素始终存在)Toggle me!
3、列表渲染指令
-
v-for
基于数组或对象循环渲染元素- {{ item.name }} (Index: {{ index }})
4、事件绑定指令
-
v-on(简写 @)
监听 DOM 事件并触发方法<button @click="handleClick">Click me</button>
5、 属性绑定指令
-
v-bind(简写 :)
动态绑定 HTML 属性(如 class、style、href 等)
6、其他实用指令
-
v-once
一次性渲染,后续数据变化不更新{{ staticMessage }}
-
v-pre
跳过编译,直接显示原始内容(用于显示插值语法 {{ }}){{ This will not be compiled }} -
v-cloak
配合 CSS 解决插值表达式闪烁问题(编译完成后隐藏){{ message }}<style>[v-cloak] { display: none; }</style>
二、Vue 3 新增指令
1、v-memo
缓存模板片段,仅在依赖变化时重新渲染(性能优化)
<div v-memo="[dependency]">
<!-- 内容仅在 dependency 变化时更新 -->
</div>
2、v-is
动态解析组件类型(用于解决原生 HTML 标签与组件名冲突的问题)
<tr v-is="'my-row-component'"></tr>
三、自定义指令
Vue 允许自定义指令,用于封装 DOM 操作(如自动聚焦、权限控制等)
1、全局注册 - vue2
Vue.directive('focus', {
inserted(el) {
el.focus();
}
});
2、局部注册 - vue2
export default {
directives: {
focus: {
inserted(el) {
el.focus();
}
}
}
};
3、使用自定义指令
<input v-focus />
4、自定义指令钩子
- bind:指令首次绑定到元素时调用。
- inserted:被绑定元素插入父节点时调用。
- update:所在组件更新时调用。
- componentUpdated:组件及子组件更新后调用。
- unbind:指令与元素解绑时调用。
四、指令对比与选择建议
| 指令 | 用途 | 适用场景 |
|---|---|---|
| v-if | 条件性渲染(销毁/重建 DOM) | 条件频繁切换时性能开销较大 |
| v-show | 通过 CSS 控制显示/隐藏 | 条件频繁切换时性能开销较大 |
| v-for | 列表渲染 | 遍历数组或对象 |
| v-model | 双向数据绑定 | 表单输入、组件通信 |
| v-bind | 动态绑定属性 | 需要动态更新 HTML 属性时 |
| v-on | 事件监听 | 用户交互事件处理 |
| v-memo | 缓存模板片段 | 大型列表性能优化 |
五、注意事项
- v-for 必须绑定 key:确保列表渲染的稳定性。
- 避免 v-if 和 v-for 共用:优先使用计算属性过滤数据。
- 自定义指令的 el 参数:指向绑定的 DOM 元素。
- Vue 3 的 v-is:替代 Vue 2 的 is 属性(用于动态组件)。
- 通过灵活使用这些指令,可以高效地实现数据驱动的动态界面和交互逻辑。
Vue3.0 自定义指令
1、全局注册
// main.js
const app = createApp(App);
app.directive('focus', {
mounted(el) { el.focus(); }
});
2、局部注册
// 组件内
export default {
directives: {
focus: {
mounted(el) { el.focus(); }
}
}
}
3、:以v开头的驼峰变量自动暴露为指令。
<script setup>
const vFocus = { mounted: (el) => el.focus() };
</script>
4、生命周期钩子
Vue3自定义指令的钩子与组件生命周期对齐,共7个:
- created:绑定元素属性/事件监听前调用(仅一次)。
- beforeMount:元素挂载父组件前调用。
- mounted:元素挂载后调用(核心操作常在此阶段)。
- beforeUpdate:父组件更新前调用。
- updated:父组件及子节点更新后调用。
- beforeUnmount:父组件卸载前调用。
- unmounted:元素解绑后调用(清理资源如事件监听)。
5、钩子参数解析
- el:绑定的DOM元素,可直接操作DOM。
- binding:包含指令值、参数、修饰符等。
value:绑定值(如v-demo="1+1"中值为2)。
arg:动态参数(如v-demo:[arg]="value")。
modifiers:修饰符对象(如.prevent、.stop)。 - vnode/prevVnode:虚拟节点,用于复杂场景。
6、核心应用场景
权限控制:根据用户权限隐藏/显示元素。
app.directive('permission', {
mounted(el, binding) {
const permissions = ['admin'];
if (!permissions.includes(binding.value)) {
el.style.display = 'none';
}
}
});
防抖点击:限制按钮短时间重复点击。
app.directive('debounce', {
mounted(el, { value = 500 }) {
let timer;
el.addEventListener('click', () => {
clearTimeout(timer);
timer = setTimeout(() => value(), value);
});
}
});
7、 Vue2 vs Vue3 区别
钩子变更:Vue2的bind、inserted等被更贴近组件生命周期的钩子替代(如mounted代替inserted)。
参数变化:binding对象新增instance(组件实例)和dir(指令定义对象)。
语法简化:支持函数形式指令(如app.directive('color', (el, binding) => el.style.color = binding.value))。
8、 最佳实践
资源清理:在unmounted钩子中移除事件监听或定时器。
响应式绑定:binding.value是响应式的,但el不是,避免直接依赖el的响应式特性。
动态参数:通过binding.arg获取动态参数(如时间单位s转换为毫秒)。