Vue 中常用的指令

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 等)

    Link

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转换为毫秒)。

相关推荐
清风细雨_林木木4 小时前
vite与vue的cli的区别
前端·javascript·vue.js
亚洲小炫风4 小时前
react 资源清单
前端·javascript·react.js
IT古董4 小时前
【前端】Headless UI 深度实战:构建可访问、可定制的现代前端组件
前端·ui
南囝coding4 小时前
Knip - 一键清理项目无用代码
前端·后端
Alice4 小时前
FVCOM Debug
开发语言·javascript·ecmascript
古蓬莱掌管玉米的神4 小时前
day 2 promote工程
javascript
五点六六六5 小时前
跨端RN 与 浏览器Web 的 长渲染性能 差异 与 底层 揭秘
前端·react native·webgl
咬人喵喵5 小时前
18 类年终总结核心 SVG 交互方案拆解
前端·css·编辑器·交互·svg
不想秃头的程序员5 小时前
JS继承方式详解
前端·面试