一文带你详解Vue常见的指令集合

342 阅读6分钟

在平常的学习和面试中,Vue常见的指令往往会被反复问到,他也贡献了很多常见的八股文,比如为什么v-for需要有key以及v-if和v-show的区别,如何创建自定义指令等等..,Vue 3 不仅提供了丰富的内置指令,还支持开发者自定义指令,极大地增强了开发的灵活性和效率。下面我们就来详细了解一下 Vue 3 的各类指令。

内部组件

1. 条件渲染指令

v-ifv-else-ifv-else
  • 功能:这组指令用于根据表达式的值来条件性地渲染元素或组件。v-if 首先判断表达式的值,如果为真则渲染元素;v-else-if 用于多个条件的判断;v-else 则是在前面条件都不满足时渲染。
  • 示例
<template>
  <div>
    <p v-if="condition === 'A'">显示 A</p>
    <p v-else-if="condition === 'B'">显示 B</p>
    <p v-else>显示其他</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const condition = ref('A');
</script>
v-show
  • 功能:根据表达式的值控制元素的显示与隐藏。它是通过修改元素的 display CSS 属性来实现的,元素始终会被渲染到 DOM 中,只是根据条件决定是否显示。

  • 示例

<template>
  <div>
    <p v-show="isShown">这是一个使用 v-show 控制显示的段落</p>
    <button @click="toggleShow">切换显示状态</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const isShown = ref(true);
const toggleShow = () => {
  isShown.value = !isShown.value;
};
</script>

2. 列表渲染指令

v-for
  • 功能:用于基于数组、对象、数字等数据源来渲染列表。可以通过解构赋值获取当前项、索引、键等信息,并且需要使用 :key 来为每个渲染项提供唯一标识,以帮助 Vue 识别节点,提高渲染效率。
  • 示例
<template>
  <div>
    <!-- 遍历数组 -->
    <ul>
      <li v-for="(fruit, index) in fruits" :key="index">{{ index }} - {{ fruit }}</li>
    </ul>
    <!-- 遍历对象 -->
    <ul>
      <li v-for="(value, key) in person" :key="key">{{ key }}: {{ value }}</li>
    </ul>
    <!-- 遍历数字 -->
    <ul>
      <li v-for="n in 5" :key="n">数字 {{ n }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const fruits = ref(['草莓', '葡萄', '西瓜']);
const person = ref({ name: '李四', age: 25, occupation: '工程师' });
</script>

3. 事件绑定指令

v-on(缩写 @
  • 功能:用于绑定 DOM 事件,当事件触发时执行对应的表达式或方法。可以绑定原生 DOM 事件,也可以绑定自定义事件。

  • 示例

<template>
  <div>
    <button @click="handleClick">点击触发事件</button>
  </div>
</template>

<script setup>
const handleClick = () => {
  console.log('按钮被点击了');
};
</script>
事件修饰符
  • .stop:阻止事件冒泡,即阻止事件继续向上层元素传播。

  • .prevent:阻止事件的默认行为,例如表单提交、链接跳转等。

  • .capture:使用事件捕获模式,事件会从外层元素开始向内层元素传播。

  • .self:只有当事件是从绑定元素本身触发时才会执行回调,而不是从其子元素触发。

  • .once:事件只会触发一次,之后该事件绑定会被移除。

  • .passive:告诉浏览器该事件处理程序不会调用 preventDefault(),可以提高滚动等事件的性能。

  • 示例

<template>
  <div>
    <form @submit.prevent="handleSubmit">
      <input type="text">
      <button type="submit">提交表单</button>
    </form>
    <div @click.capture="handleCaptureClick">
      <button @click.stop="handleStopClick">阻止冒泡</button>
    </div>
  </div>
</template>

<script setup>
const handleSubmit = () => {
  console.log('表单提交被处理');
};
const handleCaptureClick = () => {
  console.log('事件捕获触发');
};
const handleStopClick = () => {
  console.log('点击按钮,但冒泡被阻止');
};
</script>

4. 属性绑定指令

v-bind(缩写 :
  • 功能:用于动态绑定 HTML 属性、组件 props 等。可以将表达式的值绑定到元素的属性上,属性值可以是静态的,也可以是动态计算得到的。

  • 示例

<template>
  <div>
    <!-- 绑定 src 属性 -->
    <img :src="imageSource" alt="示例图片">
    <!-- 绑定 class 属性 -->
    <p :class="{ active: isActive }">这是一个动态添加类名的段落</p>
    <!-- 绑定 style 属性 -->
    <p :style="{ color: textColor }">这是一个动态设置颜色的段落</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const imageSource = ref('https://example.com/sample.jpg');
const isActive = ref(true);
const textColor = ref('red');
</script>
动态参数
  • 功能:可以使用方括号 [] 来定义动态的属性名,这样可以根据表达式的值动态地绑定不同的属性。
  • 示例
<template>
  <div>
    <button :[dynamicAttr]="dynamicValue">动态属性按钮</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const dynamicAttr = ref('disabled');
const dynamicValue = ref(true);
</script>

5. 双向数据绑定指令

v-model
  • 功能:用于在表单元素(如 inputtextareaselect 等)或自定义组件上创建双向数据绑定。它实际上是 v-bind 和 v-on 的语法糖,能够使数据的变化自动更新到视图,视图的变化也能自动更新到数据。

  • 示例

<template>
  <div>
    <input v-model="message" placeholder="请输入内容">
    <p>你输入的内容是: {{ message }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const message = ref('');
</script>
修饰符
  • .lazy:将输入框的绑定更新时机从 input 事件改为 change 事件,即只有在输入框失去焦点或按下回车键时才更新数据。
  • .number:将输入的值转换为数字类型,如果无法转换则保持原值。
  • .trim:自动过滤输入值的首尾空格。
  • 示例
<template>
  <div>
    <input v-model.lazy="lazyInput" placeholder="使用 lazy 修饰符">
    <input v-model.number="numericInput" type="number" placeholder="使用 number 修饰符">
    <input v-model.trim="trimmedInput" placeholder="使用 trim 修饰符">
  </div>
</template>

<script setup>
import { ref } from 'vue';
const lazyInput = ref('');
const numericInput = ref(0);
const trimmedInput = ref('');
</script>

自定义指令

全局自定义指令
  • 功能:可以在整个应用中使用的自定义指令,通常在创建 Vue 应用实例时进行注册。

  • 示例

// main.js
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

// 注册全局自定义指令
app.directive('highlight', {
  mounted(el, binding) {
    el.style.backgroundColor = binding.value || 'yellow';
  }
});

app.mount('#app');

vue

<!-- App.vue -->
<template>
  <div>
    <p v-highlight="'green'">这是一个使用全局自定义指令的段落</p>
  </div>
</template>
局部自定义指令
  • 功能:只能在当前组件中使用的自定义指令,在组件的 setup 函数中进行定义。

  • 示例

<template>
  <div>
    <input v-focus />
  </div>
</template>

<script setup>
import { defineDirective } from 'vue';

// 定义局部自定义指令
const focus = defineDirective({
  mounted(el) {
    el.focus();
  }
});
</script>

7. v-memo

  • 功能:这是 Vue 3 新增的指令,用于缓存一个模板的子树。当依赖项没有发生变化时,直接复用之前的渲染结果,避免不必要的重新渲染,提高性能。

  • 示例

<template>
  <div>
    <!-- 只有当 items 数组发生变化时才会重新渲染 -->
    <ul v-memo="[items]">
      <li v-for="item in items" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const items = ref([
  { id: 1, name: '项目 1' },
  { id: 2, name: '项目 2' }
]);
</script>

8. v-cloak

  • 功能:这个指令主要用于解决在 Vue 实例挂载之前,模板闪烁的问题。在 Vue 实例还未编译完成时,带有 v-cloak 的元素会被隐藏,编译完成后该指令会被移除,元素正常显示。

  • 示例

<template>
  <div v-cloak>{{ message }}</div>
</template>

<script setup>
import { ref } from 'vue';
const message = ref('加载中...');
</script>

<style scoped>
[v-cloak] {
  display: none;
}
</style>

结尾

了解了Vue的几种常见的内置组件和自定义组件之后,你可以再去看看常见的那些Vue指令八股文,是不是感觉答案也就呼之欲出了呢,前言提到的答案如下

v-ifv-show的区别

  • 渲染方式v-if是真正的条件渲染,当条件为false时,对应的 DOM 元素不会被渲染到页面中;而v-show是通过切换元素的display CSS 属性来控制显示与隐藏,无论条件真假,元素都会被渲染到页面中。
  • 性能表现:在初始渲染时,v-if有更高的切换开销,因为它需要动态地创建和销毁 DOM 元素;v-show有更高的初始渲染开销,因为它不管条件如何都会渲染元素。
  • 使用场景:如果元素可能永远不会被显示,或者在运行时条件很少改变,使用v-if更合适;如果需要频繁切换元素的显示状态,使用v-show更高效。

v-for中为什么要使用key

key是给 Vue 虚拟 DOM 的一个提示,用于在列表更新时,帮助 Vue 更高效地识别各个节点。如果不使用key,Vue 在更新列表时,可能会采用就地复用的策略,导致列表中元素的状态混乱,比如输入框的内容错位、复选框的勾选状态错误等。使用唯一的key,Vue 可以精确地找到需要更新的节点,提高更新效率,确保列表渲染的正确性和稳定性。