Vue3中的常用指令

Vue3中的指令用于控制页面元素的显示、绑定属性、绑定事件、循环渲染数据等功能,是Vue框架的核心功能之一。本文将介绍Vue3中常用的指令、缩写、使用方式、注意事项以及具体案例。

以下是Vue3中常用的指令:

指令 缩写 用途
v-if - 根据表达式的值判断是否渲染元素
v-show - 根据表达式的值控制元素的显示和隐藏
v-for - 循环渲染数据
v-bind : 动态绑定元素属性
v-model - 实现表单元素与数据双向绑定
v-on @ 绑定元素事件
v-text - 将元素的文本内容设置为表达式的值
v-html - 将元素的HTML内容设置为表达式的值
v-slot # 插槽功能,用于定义组件的模板

指令使用方式

v-ifv-show

v-ifv-show都可以根据表达式的值控制元素的显示和隐藏,但是两者的实现方式不同。v-if是动态地向DOM树中添加或删除元素,而v-show则是通过CSS控制元素的显示和隐藏。

<!-- v-if -->
<div v-if="show">
  显示的内容
</div>

<!-- v-show -->
<div v-show="show">
  显示的内容
</div>

v-for

v-for用于循环渲染数据。可以使用inof来指定数据和索引的别名,也可以使用key来提高渲染性能。(:key用来维护列表状态确保唯一)

<ul>
  <li v-for="(item, index) in list" :key="item.id">{{ item.name }}</li>
</ul>

v-bind

v-bind用于动态绑定元素属性。可以简写为:

<!-- 动态绑定class -->
<div :class="{ active: isActive }"></div>

<!-- 动态绑定style -->
<div :style="{ color: textColor }"></div>

<!-- 动态绑定属性 -->
<img :src="imageUrl" :alt="imageAlt">

v-model

v-model用于实现表单元素与数据的双向绑定。可以使用.lazy修饰符将数据绑定延迟到change事件触发时更新,也可以使用.number修饰符将输入的值转换为数值类型。

<!-- 文本输入框 -->
<input type="text" v-model="text">

<!-- 复选框 -->
<input type="checkbox" v-model="checked">

<!-- 单选框 -->
<input type="radio" value="1" v-model="radioValue">

<!-- 下拉框 -->
<select v-model="selected">
  <option value="1">选项1</option>
  <option value="2">选项2</option>
  <option value="3">选项3</option>
</select>

v-on

v-on用于绑定元素事件。可以简写为@

<!-- 绑定click事件 -->
<button @click="handleClick">点击</button>

<!-- 绑定keyup事件 -->
<input type="text" @keyup.enter="handleEnter">

v-textv-html

v-text用于将元素的文本内容设置为表达式的值,v-html用于将元素的HTML内容设置为表达式的值。需要注意的是,使用v-html会存在安全风险,因为可能会被注入恶意代码。

<!-- 设置文本内容 -->
<div v-text="message"></div>

<!-- 设置HTML内容 -->
<div v-html="htmlContent"></div>

v-slot

v-slot用于插槽功能,用于定义组件的模板。可以简写为#

<!-- 定义默认插槽 -->
<template v-slot>
  默认插槽的内容
</template>

<!-- 定义具名插槽 -->
<template v-slot:header>
  插槽header的内容
</template>

指令注意事项

在使用指令时,需要注意以下几点:

  • 指令的值可以是一个表达式或者一个方法;
  • 在使用v-if指令时,如果表达式的值为假,则对应的元素不会被渲染;
  • 在使用v-for指令时,要为每个子元素添加一个唯一的key值,以提高渲染性能;
  • 在使用v-bind指令时,可以简写为:prop
    • 在Vue.js中,当在模板中使用一个变量时,需要用 : 来将该变量绑定到对应的属性上,这就是所谓的 “v-bind” 语法。因此,当我们在模板中使用 startYear 时,需要使用 :startYear 的形式进行绑定。对于字符串类型的属性,可以不使用 : 来绑定,而是直接传递一个字符串。因此,icpNumber 和 author 可以直接传递字符串,而不需要使用 :。
  • 在使用v-on指令时,可以简写为@event
  • 在使用v-slot指令时,需要注意插槽的作用域。

案例分析

以下是一个简单的Vue3组件,使用了上述指令:

<template>
  <div>
    <div v-if="show">显示的内容</div>
    <div v-for="(item, index) in list" :key="item.id">{{ item.name }}</div>
    <div :class="{ active: isActive }">动态绑定class</div>
    <select v-model="selected">
      <option value="1">选项1</option>
      <option value="2">选项2</option>
      <option value="3">选项3</option>
    </select>
    <input type="text" v-model="text">
    <button @click="handleClick">点击</button>
    <div v-text="message"></div>
    <div v-html="htmlContent"></div>
    <slot name="header"></slot>
    <slot></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true,
      list: [{ id: 1, name: 'item1' }, { id: 2, name: 'item2' }, { id: 3, name: 'item3' }],
      isActive: true,
      selected: '2',
      text: '',
      message: '显示的文本',
      htmlContent: '<b>显示的HTML</b>'
    }
  },
  methods: {
    handleClick() {
      console.log('按钮被点击了')
    }
  }
}
</script>

在这个组件中,使用了v-if指令来根据show的值来显示或隐藏一个元素;使用了v-for指令来循环渲染一个数组;使用了:key来提高循环渲染的性能;使用了:class来动态绑定class;使用了v-model指令来实现表单元素的双向绑定;使用了v-textv-html指令来设置元素的文本和HTML内容;使用了v-on指令来绑定点击事件;使用了v-slot指令来定义插槽。

如果没有这些指令,我们就需要手动编写一些逻辑代码来实现类似的功能,这不仅繁琐,而且容易出错。因此,Vue3的指令是非常有用的,它们可以大大提高开发效率,简化代码编写。

补充一下插槽的概念和场景应用

Vue3中的插槽语法可以让我们在父组件中定义子组件的一部分内容,具体场景可以是一个复杂的组件中,其中包含多个子组件,而这些子组件需要在某些位置插入一些特定的内容。

使用插槽语法,我们可以在父组件中使用<slot>标签来定义插槽,然后在子组件中使用<slot>标签来指定插槽的位置。当子组件被渲染时,插槽会被父组件中定义的内容所替换。

简写

  • v-slot可以简写为#

    • 必须包裹在<template>标签中
  • v-bind也可以简写,前面也提及了

  • 若不指明插槽名字,那默认就是default

普通插槽

以下是一个简单的例子,使用插槽来定义一个带有标题和内容的卡片组件:

<!-- 父组件 -->
<Card>
  <template #title>
    <h2>Card Title</h2>
  </template>
  <template #content>
    <p>This is the card content.</p>
  </template>
</Card>

<!-- 子组件 -->
<template>
  <div class="card">
    <div class="card-title">
      <slot name="title"></slot>
    </div>
    <div class="card-content">
      <slot name="content"></slot>
    </div>
  </div>
</template>

在上面的例子中,父组件<Card>中定义了两个插槽,分别用#title#content来指定。在子组件中,我们使用<slot>标签来指定插槽的位置,并使用name属性来指定插槽的名称。

作用域插槽

除了基本的插槽语法外,Vue3还提供了一些高级的插槽功能。例如,我们可以使用v-bind指令来动态地向插槽中传递数据:

<!-- 父组件 -->
<Card>
  <template #title>
    <h2>{{ cardTitle }}</h2>
  </template>
  <template #content="{ cardContent }">
    <p>{{ cardContent }}</p>
  </template>
</Card>

<!-- 子组件 -->
<template>
  <div class="card">
    <div class="card-title">
      <slot name="title"></slot>
    </div>
    <div class="card-content">
      <slot name="content" v-bind="{ cardContent }"></slot>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cardTitle: "Card Title",
      cardContent: "This is the card content.",
    };
  },
};
</script>

在上面的例子中,父组件使用了对象解构的方式来传递数据到插槽中。子组件则使用v-bind指令来将父组件中的数据传递给插槽。

另外,Vue3还提供了作用域插槽的语法,可以让我们在子组件中访问父组件中的数据。支持解构赋值,例如:

<!-- 父组件 -->
<Card>
  <template #title="{ cardTitle }">
    <h2>{{ cardTitle }}</h2>
  </template>
  <template #content="{ cardContent }">
    <p>{{ cardContent }}</p>
  </template>
</Card>

<!-- 子组件 -->
<template>
  <div class="card">
    <div class="card-title">
      <slot name="title" v-bind="{ cardTitle: title }"></slot>
    </div>
    <div class="card-content">
      <slot name="content" v-bind="{ cardContent: content }"></slot>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: "Card Title",
    },
    content: {
      type: String,
      default: "This is the card content.",
    },
  },
};
</script>

在上面的例子中,父组件使用了对象解构的方式来将数据传递给插槽。子组件则使用v-bind指令来将父组件中的数据传递给插槽,并使用{ cardTitle }{ cardContent }

其他指令

  • v-once:只渲染一次,之后值更新不会再渲染
  • v-memo:接受的是数组,一般配合v-for使用,但其实用的非常少
    • 对性能有一点比较小的优化提升
    • 通俗来讲就是会对满足数组中某些条件的项会选择跳过之类的,具体的去看文档吧