Vue 3 提供了多种指令(Directives),用于在模板中对元素或组件的行为进行绑定和处理。指令是以 v- 开头的特殊属性,它们会在 Vue 组件实例的生命周期中执行,并通过它们来控制 DOM 的呈现和行为。

1. 常用内置指令

v-bind

v-bind 用于动态绑定 HTML 属性。常用于绑定元素的属性、类、样式等。

<template>
  <img v-bind:src="imageUrl" alt="Vue Logo">
</template>

<script>
export default {
  data() {
    return {
      imageUrl: 'https://vuejs.org/images/logo.png'
    };
  }
};
</script>

你也可以使用 : 来简写 v-bind

<template>
  <img :src="imageUrl" alt="Vue Logo">
</template>

v-model

v-model 用于双向绑定输入表单元素的数据。它会自动将输入值绑定到 Vue 实例的数据属性。

<template>
  <input v-model="message" />
  <p>{{ message }}</p>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue 3!'
    };
  }
};
</script>

v-if / v-else-if / v-else

v-if 用于条件渲染,当条件为 true 时渲染元素。如果为 false,则不渲染。

<template>
  <p v-if="isVisible">This is visible when isVisible is true.</p>
  <p v-else>If isVisible is false, this will be shown.</p>
</template>

<script>
export default {
  data() {
    return {
      isVisible: false
    };
  }
};
</script>

v-for

v-for 用于列表渲染。你可以遍历数组或对象,并动态渲染对应的元素。

<template>
  <ul>
    <li v-for="(item, index) in items" :key="index">{{ item }}</li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      items: ['Apple', 'Banana', 'Orange']
    };
  }
};
</script>

v-show

v-show 也是用于条件渲染,但它通过 CSS 来控制元素的可见性,而不是直接从 DOM 中移除元素。元素始终会存在,只是通过 display: none 来隐藏它。

<template>
  <p v-show="isVisible">This text will toggle visibility with v-show.</p>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  }
};
</script>

v-on

v-on 用于监听 DOM 事件并触发方法。你可以使用 @ 来简写 v-on

<template>
  <button @click="changeMessage">Click me</button>
  <p>{{ message }}</p>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue 3!'
    };
  },
  methods: {
    changeMessage() {
      this.message = 'Button was clicked!';
    }
  }
};
</script>

v-bind:classv-bind:style

v-bind:class 用于动态绑定 CSS 类,v-bind:style 用于动态绑定样式。

<template>
  <div :class="classObject" :style="styleObject">Hello, Vue 3!</div>
</template>

<script>
export default {
  data() {
    return {
      isActive: true,
      hasError: false,
      classObject: {
        active: this.isActive,
        'text-danger': this.hasError
      },
      styleObject: {
        color: 'red',
        fontSize: '20px'
      }
    };
  }
};
</script>

2. 自定义指令

除了 Vue 提供的内置指令,你还可以创建自定义指令。在 Vue 3 中,可以通过 app.directive 注册全局指令,或在单个组件中使用局部指令。

注册全局指令

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

const app = createApp(App);

app.directive('focus', {
  mounted(el) {
    el.focus();
  }
});

app.mount('#app');

然后你可以在模板中使用该自定义指令:

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

局部指令

你也可以在单个组件内注册指令:

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

<script>
export default {
  directives: {
    focus: {
      mounted(el) {
        el.focus();
      }
    }
  }
};
</script>

3. 指令钩子

每个指令可以有不同的钩子函数,分别对应不同的生命周期阶段。这些钩子允许你在指令的不同阶段执行操作。Vue 3 的指令钩子如下:

  • created:指令绑定到元素时调用
  • beforeMount:元素挂载之前调用
  • mounted:元素挂载后调用
  • beforeUpdate:指令的所在元素被更新之前调用
  • updated:指令的所在元素被更新后调用
  • beforeUnmount:指令的所在元素被卸载前调用
  • unmounted:指令的所在元素被卸载后调用

例如,在自定义指令中使用钩子:

app.directive('focus', {
  mounted(el) {
    el.focus();
  },
  updated(el) {
    console.log('Element updated!');
  }
});

4. 修饰符

修饰符是用于附加到指令上的特殊标记,通常用于某些特定行为的控制。例如,v-on 事件指令有 .prevent.stop 等修饰符。

.prevent 修饰符

它阻止了事件的默认行为:

<template>
  <form @submit.prevent="submitForm">Submit</form>
</template>

.stop 修饰符

它阻止事件冒泡:

<template>
  <button @click.stop="handleClick">Click me</button>
</template>

.once 修饰符

它使得事件只触发一次:

<template>
  <button @click.once="handleClick">Click me</button>
</template>

.lazy 修饰符

用于 v-model,它只在 change 事件触发时才更新绑定的值,而不是每次输入时都更新:

<template>
  <input v-model.lazy="message" />
</template>

总结

Vue 3 的指令为我们提供了灵活、强大的工具,使得在模板中操作 DOM 更加简单和高效。常用的内置指令如 v-bindv-modelv-ifv-forv-on 等都极大地方便了开发。通过自定义指令和指令钩子,你还可以为 Vue 组件和应用扩展更多功能。

指令不仅仅是数据绑定的工具,还可以通过修饰符来精细化控制事件和行为,从而使得模板更加简洁、易用。