vue 指令从入门到精通

1. Vue3 指令是什么?

Vue3 指令是一种特殊的属性,以 v- 前缀开头,用于在 DOM 元素上应用特殊的响应式行为。指令本质上是当表达式的值改变时,会产生副作用,即响应式地作用于 DOM。指令可以让开发者以声明式编程的方式操作 DOM,无需直接接触底层 DOM API。

2. Vue3常见的指令

以下是 Vue3 中常见的指令:

  1. v-bind:动态绑定属性或组件 prop 到表达式。常简写为冒号(:)。

    <img v-bind:src="imageSrc"> <!-- 完整写法 -->
    <img :src="imageSrc"> <!-- 简写 -->
    
  2. v-model:在表单元素或组件上创建双向绑定。

    <input v-model="message">
    
  3. v-if/v-else-if/v-else:条件性地渲染元素。

    <div v-if="type === 'A'">A</div>
    <div v-else-if="type === 'B'">B</div>
    <div v-else>Not A/B</div>
    
  4. v-show:根据条件显示或隐藏元素(通过 CSS display 属性)。

    <div v-show="isVisible">内容</div>
    
  5. v-for:基于源数据多次渲染元素或模板块。

    <li v-for="(item, index) in items" :key="item.id">
      {{ index }} - {{ item.name }}
    </li>
    
  6. v-on:绑定事件监听器。常简写为 @

    <button v-on:click="doSomething">点击</button> <!-- 完整写法 -->
    <button @click="doSomething">点击</button> <!-- 简写 -->
    
  7. v-slot:提供具名插槽或接收 prop 的插槽。常简写为 #

    <template v-slot:header>头部内容</template> <!-- 完整写法 -->
    <template #header>头部内容</template> <!-- 简写 -->
    
  8. v-pre:跳过该元素及其子元素的编译过程。

    <span v-pre>{{ 这里的内容不会被编译 }}</span>
    
  9. v-once:只渲染元素和组件一次,后续的重新渲染会被跳过。

    <span v-once>{{ message }}</span>
    
  10. v-text:更新元素的文本内容。

    <span v-text="message"></span>
    
  11. v-html:更新元素的 innerHTML(需谨慎使用,避免 XSS 攻击)。

    <div v-html="htmlContent"></div>
    
  12. v-cloak:保持在元素上直到关联实例结束编译,配合 CSS 规则使用。

    <div v-cloak>{{ message }}</div>
    
  13. v-memo:Vue 3.2 新增,用于记忆和跳过更新整个子树。

    <div v-memo="[valueA, valueB]">...</div>
    
  14. 自定义指令:Vue3 还允许开发者创建自定义指令来满足特定需求。

Vue3 的指令系统是其响应式编程模型的重要组成部分,让开发者能够以简洁直观的方式处理视图层的各种逻辑。

3. Vue3 指令原理解析

3.1. Vuu3 v-bind:原理形象讲解以及前端的具体表现示意

1. v-bind 原理讲解

在 Vue.js 中,v-bind 是一个指令,用于动态绑定一个 HTML 属性或者特性到一个 Vue 实例的数据属性上。通过 v-bind,我们可以将 Vue 组件的数据与 DOM 元素的属性动态绑定,这意味着当数据变化时,HTML 属性会随之自动更新。

  • 原理v-bind 会监听 Vue 实例中指定的数据属性,当该数据属性发生变化时,v-bind 会自动更新 DOM 元素的属性值。这样,开发者不需要手动操作 DOM,就能实现动态的属性绑定。

  • 简洁写法v-bind 可以缩写为冒号(:)。例如,v-bind:href 可以写成 :href,效果相同。


2. v-bind 的常见用法
(1) 动态绑定 href 属性

假设你有一个链接,它的 href 属性需要根据 Vue 数据动态改变。你可以使用 v-bind 来绑定这个属性:

<template>
  <a :href="url">点击访问</a>
</template>

<script>
export default {
  data() {
    return {
      url: "https://www.example.com"
    };
  }
};
</script>
  • 原理:当 url 变量发生变化时,v-bind 会自动更新 <a> 标签的 href 属性。

(2) 动态绑定 class 属性

通过 v-bind,我们可以根据数据动态控制元素的 CSS 类。假设我们有一个按钮,它的背景颜色需要根据一个布尔值 isActive 来决定:

<template>
  <button :class="{'active': isActive, 'inactive': !isActive}">
    {{ isActive ? '激活' : '禁用' }}
  </button>
</template>

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

<style>
.active {
  background-color: green;
}
.inactive {
  background-color: gray;
}
</style>
  • 原理v-bind:class 动态地根据 isActive 的值为按钮添加不同的 CSS 类。当 isActivetrue 时,按钮背景为绿色(active 类),否则背景为灰色(inactive 类)。

(3) 动态绑定 style 属性

v-bind 也可以用来动态绑定内联样式。假设我们希望根据数据改变元素的背景颜色:

<template>
  <div :style="{ backgroundColor: color }">
    动态背景颜色
  </div>
</template>

<script>
export default {
  data() {
    return {
      color: 'red'
    };
  }
};
</script>
  • 原理v-bind:style 会根据 color 数据的变化,动态更新元素的 style 属性,从而改变背景颜色。

3. v-bind 前端的具体表现示意
**(1) 动态绑定 href 示例

前端界面:

<a :href="url">点击访问</a>
  • url = "https://www.example.com" 时,点击链接会跳转到该网址。
(2) 动态绑定 class 示例

前端界面:

<button :class="{'active': isActive, 'inactive': !isActive}">
  {{ isActive ? '激活' : '禁用' }}
</button>
  • 如果 isActive = true,按钮会呈现绿色背景,且文字显示为“激活”。
  • 如果 isActive = false,按钮会呈现灰色背景,且文字显示为“禁用”。
(3) 动态绑定 style 示例

前端界面:

<div :style="{ backgroundColor: color }">
  动态背景颜色
</div>
  • 如果 color = 'red',背景颜色会变为红色。
  • 如果 color = 'blue',背景颜色会变为蓝色。

4. 小结

v-bind 是 Vue 中非常强大的动态绑定功能,通过它我们可以将 Vue 数据与 HTML 属性、类、样式等绑定起来。当数据变化时,相关的属性、类或样式会自动更新,无需手动操作 DOM,极大地提升了开发效率和代码的可维护性。

3.2. Vuu3 v-model:原理形象讲解以及前端的具体表现示意

1. v-model 原理讲解

在 Vue3 中,v-model 是一个非常常用的指令,用于在父子组件之间进行数据的双向绑定。它能够使得一个组件的输入(如文本框、复选框等)与数据模型同步变化,反过来,当数据模型变化时,组件的显示内容也会自动更新。

原理

  • 双向绑定v-model 实现了数据与视图之间的双向绑定。它自动同步父组件与子组件的数据。
    • 当子组件中的值发生变化时,父组件中的数据也会发生更新。
    • 当父组件中的数据发生变化时,子组件中的值会同步更新。
  • v-model 的默认行为:它将会自动绑定到组件的 modelValue 属性,监听 input 事件来同步更新数据。

在 Vue3 中,v-model 的行为发生了一些变化,默认绑定的是 modelValue,而不是 Vue2 中的 value 属性。


2. v-model 的用法
(1) 基本用法:输入框的双向绑定

一个常见的场景是使用 v-model 来实现表单元素的双向数据绑定。例如,使用 v-model 绑定一个文本框的值:

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

<script>
export default {
  data() {
    return {
      message: ""
    };
  }
};
</script>
  • 原理:在这个例子中,v-model 会将 message 绑定到 <input> 元素上。当你在文本框中输入内容时,message 会实时更新。反之,当 message 的值发生变化时,文本框中的内容也会自动更新。

(2) 使用 v-model 绑定自定义组件的属性

在 Vue3 中,v-model 也可以用于自定义组件的双向绑定。例如,假设有一个自定义的 my-input 组件,父组件希望双向绑定它的值。

父组件:

<template>
  <my-input v-model="parentMessage"></my-input>
  <p>父组件中的数据:{{ parentMessage }}</p>
</template>

<script>
import MyInput from './MyInput.vue';

export default {
  components: {
    MyInput
  },
  data() {
    return {
      parentMessage: ''
    };
  }
};
</script>

子组件 MyInput.vue

<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</template>

<script>
export default {
  props: {
    modelValue: String
  }
};
</script>
  • 原理:父组件通过 v-model 传递数据给子组件,子组件通过 modelValue 接收父组件的数据。当子组件中的输入框内容发生变化时,使用 $emit('update:modelValue', newValue) 向父组件发送更新事件,更新父组件中的数据。

(3) 多个 v-model 用法(Vue 3 中的新特性)

Vue 3 引入了对多个 v-model 的支持,允许我们在同一组件中使用多个 v-model 绑定不同的属性。

父组件:

<template>
  <my-input v-model:username="username" v-model:age="age"></my-input>
  <p>用户名:{{ username }}</p>
  <p>年龄:{{ age }}</p>
</template>

<script>
import MyInput from './MyInput.vue';

export default {
  components: {
    MyInput
  },
  data() {
    return {
      username: '',
      age: 25
    };
  }
};
</script>

子组件 MyInput.vue

<template>
  <input :value="username" @input="$emit('update:username', $event.target.value)">
  <input :value="age" @input="$emit('update:age', $event.target.value)">
</template>

<script>
export default {
  props: {
    username: String,
    age: Number
  }
};
</script>
  • 原理:通过 v-model:usernamev-model:age,父组件能够将 usernameage 分别绑定到子组件的两个不同属性上。在子组件中,我们通过 update:usernameupdate:age 事件来更新父组件中的数据。

3. v-model 前端的具体表现示意
(1) 基本双向绑定(文本框)

前端界面:

<input v-model="message" placeholder="请输入内容">
<p>输入的内容是:{{ message }}</p>
  • 用户输入 Hellomessage 的值将实时更新为 Hello,并且 <p> 标签中的内容也会自动显示 Hello
(2) 双向绑定自定义组件

假设有一个自定义组件 MyInput,父组件传递 message 数据,子组件通过 v-model 绑定。

前端界面:

<my-input v-model="message"></my-input>
<p>父组件中的数据:{{ message }}</p>
  • 在自定义组件的 <input> 中输入内容时,message 会更新,父组件中的 <p> 标签也会显示该内容。
(3) 多个 v-model 用法

在父组件中,使用多个 v-model 双向绑定:

前端界面:

<my-input v-model:username="username" v-model:age="age"></my-input>
<p>用户名:{{ username }}</p>
<p>年龄:{{ age }}</p>
  • 在子组件的两个输入框中输入用户名和年龄时,父组件中的 usernameage 数据会实时更新,并显示在相应的 <p> 标签中。

4. 小结
  • v-model 在 Vue3 中实现了数据的双向绑定,使得父子组件之间的通信更加简单和直观。
  • 它支持文本框、复选框、选择框等表单控件的双向数据绑定,自动处理数据与视图的同步。
  • 在自定义组件中,v-model 会绑定 modelValue 属性,子组件通过 $emit('update:modelValue', newValue) 更新父组件的数据。
  • Vue3 新增了对多个 v-model 的支持,允许我们在同一组件中同时双向绑定多个属性。

v-model 是实现用户输入、表单处理和组件间数据流通的重要工具,能够显著提高开发效率。

3.3. Vue3 v-if/v-else-if/v-else:原理形象讲解以及前端的具体表现示意

1. v-if / v-else-if / v-else 原理讲解

在 Vue3 中,v-ifv-else-ifv-else 是用于条件渲染的指令。它们通过控制某个元素是否渲染到 DOM 中来实现条件显示的效果。

  • v-if:根据表达式的布尔值决定是否渲染某个元素。如果 v-if 后面的表达式返回 true,该元素将被渲染;如果返回 false,该元素不会被渲染。

  • v-else-if:在 v-if 条件为 false 时,v-else-if 用来判断其他条件。如果 v-iffalsev-else-if 的条件为 true,则渲染对应的元素。它必须紧跟在 v-if 或另一个 v-else-if 后面。

  • v-else:当 v-ifv-else-if 的条件都为 false 时,v-else 会渲染对应的元素。它必须紧跟在 v-ifv-else-if 的后面,并且不需要表达式。

原理

  • Vue 会根据表达式的计算结果来判断是否插入或移除 DOM 元素,条件的变化会触发视图的重新渲染。这样能够实现动态显示和隐藏某些元素。
2. v-if / v-else-if / v-else 的常见用法
(1) v-if 的基本用法

v-if 可以直接在 HTML 元素上使用,来控制其是否显示。

<template>
  <p v-if="isVisible">这个内容是显示的!</p>
  <button @click="isVisible = !isVisible">切换显示</button>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  }
};
</script>
  • 原理:当 isVisibletrue 时,<p> 标签会被渲染出来。如果 isVisiblefalse<p> 标签则会被移除。
(2) v-else-ifv-else 的使用

v-else-ifv-else 常用于多条件的情况,用于在多个条件之间进行切换。

<template>
  <div>
    <p v-if="status === 'loading'">加载中...</p>
    <p v-else-if="status === 'success'">加载成功!</p>
    <p v-else>加载失败!</p>
    <button @click="status = 'loading'">加载中</button>
    <button @click="status = 'success'">加载成功</button>
    <button @click="status = 'error'">加载失败</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      status: 'loading'  // 初始状态为 loading
    };
  }
};
</script>
  • 原理v-if 判断是否显示“加载中…”,v-else-if 判断是否显示“加载成功!”,v-else 会显示“加载失败!”。
  • 通过点击不同的按钮,修改 status 的值,从而切换显示不同的文本。
3. v-if / v-else-if / v-else 前端的具体表现示意
(1) v-if 示例

在前端界面中,如果 isVisibletrue,则显示段落内容“这个内容是显示的!”。点击“切换显示”按钮时,isVisible 的值会发生变化,从而控制 <p> 标签的显示与隐藏。

<p v-if="isVisible">这个内容是显示的!</p>
<button @click="isVisible = !isVisible">切换显示</button>
  • isVisibletrue,页面会显示:

    这个内容是显示的!
    切换显示
    
  • isVisiblefalse,页面会隐藏该段落,只显示按钮:

    切换显示
    
(2) v-else-ifv-else 示例

此示例展示了根据 status 状态的不同值,显示不同的消息。点击按钮会触发不同的状态值,从而显示不同的内容。

<p v-if="status === 'loading'">加载中...</p>
<p v-else-if="status === 'success'">加载成功!</p>
<p v-else>加载失败!</p>
<button @click="status = 'loading'">加载中</button>
<button @click="status = 'success'">加载成功</button>
<button @click="status = 'error'">加载失败</button>
  • status = 'loading',显示:

    加载中...
    加载中
    
  • status = 'success',显示:

    加载成功!
    加载成功
    
  • status = 'error',显示:

    加载失败!
    加载失败
    
4. 小结
  • v-if:用于根据条件来控制元素的显示与隐藏。
  • v-else-if:用于在 v-iffalse 的情况下进一步判断其他条件。
  • v-else:用于当所有前面的条件都为 false 时,显示默认内容。

通过这些条件渲染指令,可以轻松地根据不同的条件展示或隐藏元素,控制视图的变化,并且可以根据多个条件灵活展示不同的内容。v-if 适合需要根据复杂条件进行条件渲染的场景,而 v-else-ifv-else 则用于多个条件之间的选择。

3.4. Vue3 v-show:原理形象讲解以及前端的具体表现示意

1. v-show 原理讲解

在 Vue3 中,v-show 是另一种用于控制元素显示与隐藏的指令。与 v-if 不同,v-show 并不通过移除或插入 DOM 元素来控制显示与隐藏,而是通过动态修改元素的 display 样式来控制显示。

  • 原理

    • v-show 通过设置元素的 CSS display 样式来控制其显示与隐藏。当绑定的表达式为 true 时,元素的 display 会被设置为 block(或其他适合该元素的值);当为 false 时,display 会被设置为 none,使元素隐藏。
    • 不同于 v-ifv-show 会始终渲染元素,但会根据条件通过改变 display 样式来决定元素是否可见。因此,v-show 在频繁切换显示与隐藏的场景中会比 v-if 更高效,因为它不需要反复添加或移除 DOM 元素。
  • 适用场景

    • 如果某个元素需要频繁地在显示与隐藏之间切换,并且不需要频繁销毁和重建 DOM 元素,使用 v-show 更为合适。
    • 如果元素初始状态不需要渲染,且只需要一次性的渲染,使用 v-if 会更有效。

2. v-show 的常见用法
(1) 基本用法:切换元素的显示与隐藏

使用 v-show 来控制一个元素的显示与隐藏,可以通过绑定一个布尔值。

<template>
  <p v-show="isVisible">这个内容是可见的!</p>
  <button @click="isVisible = !isVisible">切换显示</button>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  }
};
</script>
  • 原理:初始状态下,isVisibletrue,因此 <p> 元素显示。当点击按钮时,isVisible 的值发生变化,<p> 元素的 display 样式会在 blocknone 之间切换,从而控制元素的显示与隐藏。
(2) v-showv-if 的对比

在某些情况下,v-showv-if 都可以用来控制元素的显示与隐藏,但它们的实现机制不同。以下是一个简单的对比示例,展示了两者的区别:

<template>
  <div>
    <p v-show="isVisible">这是使用 v-show 的内容</p>
    <p v-if="isVisible">这是使用 v-if 的内容</p>
    <button @click="isVisible = !isVisible">切换显示</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  }
};
</script>
  • 原理
    • v-show 会始终渲染 <p> 元素,并通过切换其 display 样式来控制显示与隐藏。即使 isVisiblefalse,该元素依然存在于 DOM 中,只是被隐藏。
    • v-if 会在 isVisiblefalse 时移除 DOM 元素,重新切换时再将元素插入 DOM 中。
3. v-show 前端的具体表现示意
(1) v-show 示例

在此示例中,当 isVisibletrue 时,段落内容会显示;当点击按钮时,isVisible 的值会改变,从而控制 <p> 元素的显示与隐藏。

<p v-show="isVisible">这个内容是可见的!</p>
<button @click="isVisible = !isVisible">切换显示</button>
  • isVisible = true 时,显示:

    这个内容是可见的!
    切换显示
    
  • isVisible = false 时,显示:

    切换显示
    
(2) v-showv-if 的对比表现
<p v-show="isVisible">这是使用 v-show 的内容</p>
<p v-if="isVisible">这是使用 v-if 的内容</p>
<button @click="isVisible = !isVisible">切换显示</button>
  • isVisible = true 时,v-showv-if 的内容都会显示,按钮可用:

    这是使用 v-show 的内容
    这是使用 v-if 的内容
    切换显示
    
  • isVisible = false 时,v-show 会保持该元素在 DOM 中,只是隐藏,而 v-if 会从 DOM 中移除该元素:

    • v-show 隐藏:``(没有显示任何内容)
    • v-if 移除元素:``(没有显示任何内容)

4. 小结
  • v-show 通过切换元素的 display 样式来控制元素的显示与隐藏。元素始终会存在于 DOM 中,只是其显示状态会发生变化。
  • v-if 会在条件为 false 时移除 DOM 元素,且需要重新渲染时重新插入 DOM。v-if 在频繁切换时性能较差,但适用于条件较少变化的情况。
  • 适用场景v-show 适合用于需要频繁切换显示与隐藏的场景(如 tab 切换、动画效果等),而 v-if 更适合用于不频繁切换的场景,且条件复杂时更优。

性能差异

  • v-if 会动态地添加或移除 DOM 元素,适合条件不常变化的情况。
  • v-show 会始终渲染元素并通过修改 display 样式来控制显示与隐藏,适合需要频繁切换显示的场景。

3.5. Vue3 v-for:原理形象讲解以及前端的具体表现示意

1. v-for 原理讲解

在 Vue3 中,v-for 是一个用于循环渲染列表数据的指令。它使得我们能够基于一个数组或对象,重复渲染元素或组件。v-for 会根据提供的数组或对象的数据来创建多个 DOM 元素,每个元素都基于数据的一个项进行渲染。

  • 原理v-for 会根据传入的数据(数组或对象)重复渲染元素或组件。每次渲染时,Vue 会为每个元素或组件生成一个唯一的标识(通常是基于项的索引或某个唯一值),并通过这个标识来优化更新和渲染过程。

    1. 数组循环v-for 用来遍历数组时,会生成多个相同结构的 DOM 元素。
    2. 对象循环v-for 用来遍历对象时,会为对象的每个键值对生成多个元素。

2. v-for 的常见用法
(1) 数组的循环渲染

v-for 最常见的用法是循环渲染数组中的元素。例如,渲染一个简单的数组列表:

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

<script>
export default {
  data() {
    return {
      items: ["苹果", "香蕉", "橙子"]
    };
  }
};
</script>
  • 原理v-for="(item, index) in items" 遍历数组 items,其中 item 是当前项,index 是当前项的索引。每个 <li> 元素会显示数组中的每个项及其索引。
  • key 属性key="index" 是一个优化,帮助 Vue 在列表更新时高效地复用 DOM 元素,提高渲染性能。
(2) 对象的循环渲染

当我们需要渲染对象中的键值对时,可以使用 v-for 来遍历对象。例如:

<template>
  <ul>
    <li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      user: {
        name: "John",
        age: 30,
        location: "New York"
      }
    };
  }
};
</script>
  • 原理v-for="(value, key) in user" 遍历 user 对象的每个属性,key 是属性名,value 是属性值。每个 <li> 会显示 key: value
(3) 循环渲染组件

v-for 也可以用于循环渲染组件。例如,如果我们有一个用户列表,且每个用户是一个自定义组件,可以像这样渲染多个组件:

<template>
  <div>
    <user-card v-for="(user, index) in users" :key="user.id" :user="user"></user-card>
  </div>
</template>

<script>
import UserCard from "./UserCard.vue";

export default {
  components: {
    UserCard
  },
  data() {
    return {
      users: [
        { id: 1, name: "Alice", age: 25 },
        { id: 2, name: "Bob", age: 30 },
        { id: 3, name: "Charlie", age: 28 }
      ]
    };
  }
};
</script>
  • 原理:使用 v-for 来渲染 UserCard 组件,对于每个 user,传递一个 user 对象作为组件的 prop。key="user.id" 帮助 Vue 更好地识别和更新每个组件实例。

3. v-for 前端的具体表现示意
(1) 数组渲染列表

假设有一个简单的水果数组,使用 v-for 渲染列表:

<ul>
  <li v-for="(item, index) in items" :key="index">{{ index + 1 }}. {{ item }}</li>
</ul>
  • 数据items = ["苹果", "香蕉", "橙子"]

  • 表现

    1. 苹果
    2. 香蕉
    3. 橙子
    

items 数组发生变化时(比如添加、删除或修改元素),Vue 会根据 key 属性优化 DOM 更新,避免不必要的重新渲染。

(2) 对象渲染键值对

假设有一个用户对象,使用 v-for 渲染键值对:

<ul>
  <li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li>
</ul>
  • 数据user = { name: "John", age: 30, location: "New York" }

  • 表现

    name: John
    age: 30
    location: New York
    

user 对象中的值发生变化时,DOM 会自动更新,显示新的内容。

(3) 渲染组件列表

假设你有一个 UserCard 组件,并用 v-for 渲染多个用户的卡片:

<div>
  <user-card v-for="(user, index) in users" :key="user.id" :user="user"></user-card>
</div>
  • 数据users = [{ id: 1, name: "Alice", age: 25 }, { id: 2, name: "Bob", age: 30 }]
  • 表现
    • 会显示两个 UserCard 组件,每个组件展示一个用户的名称和年龄。

4. 小结
  • v-for 是 Vue 中用于循环渲染数组、对象或组件列表的指令。
  • 当遍历 数组 时,v-for 会为每个元素生成一个 DOM 元素;遍历 对象 时,v-for 会生成每个属性的键值对。
  • key 属性在 v-for 中非常重要,它帮助 Vue 跟踪每个元素的身份,从而优化 DOM 更新。
  • 适用场景v-for 在需要动态生成多个元素或组件时非常有用,如列表、表格、卡片组件等。
  • 相比直接操作 DOM,使用 v-for 能更简洁地实现动态渲染,并且 Vue 会自动处理数据变化和视图更新。

性能提示:尽量为每个 v-for 渲染的元素指定唯一的 key,避免使用数组索引作为 key,因为这可能会导致 Vue 错误地复用 DOM 元素,从而影响性能和行为。

3.6. Vue3 v-on:原理形象讲解以及前端的具体表现示意

1. v-on 原理讲解

在 Vue3 中,v-on 是一个用于监听 DOM 事件并执行相应方法的指令。它用于给元素绑定事件监听器,并在事件触发时执行指定的回调函数。

  • 原理

    • v-on 允许开发者将 DOM 事件(如 clickinputmouseover 等)与 Vue 实例中的方法或表达式绑定。当事件被触发时,Vue 会调用指定的方法,并将事件对象传递给它。
    • v-on 可以用来监听用户与界面互动时产生的各种事件,并且可以通过事件修饰符(如 .prevent.stop 等)来控制事件的默认行为或传播。
  • 简写形式

    • v-on 可以使用冒号(:)作为简写形式。例如,v-on:click 可以写作 @click,效果相同。

2. v-on 的常见用法
(1) 基本用法:监听事件

v-on 最基本的用法是为元素绑定事件监听器,并指定要执行的回调函数。

<template>
  <button v-on:click="handleClick">点击我</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      alert("按钮被点击了!");
    }
  }
};
</script>
  • 原理:当按钮被点击时,Vue 会调用 handleClick 方法,并弹出一个提示框“按钮被点击了!”
(2) 使用简写语法

Vue3 支持事件的简写形式,可以使用 @ 来代替 v-on,使代码更加简洁。

<template>
  <button @click="handleClick">点击我</button>
</template>
  • 原理@clickv-on:click 的简写形式。当按钮被点击时,handleClick 方法会被执行。
(3) 传递事件对象

在事件回调函数中,我们可以接收原生的事件对象,通常事件对象会作为回调函数的第一个参数传递。

<template>
  <button @click="handleClick">点击我</button>
</template>

<script>
export default {
  methods: {
    handleClick(event) {
      console.log(event);  // 打印原生事件对象
    }
  }
};
</script>
  • 原理event 是原生的 JavaScript 事件对象,包含了事件的相关信息,如目标元素、事件类型等。当按钮被点击时,event 对象会被传递给 handleClick 方法。
(4) 事件修饰符

Vue3 允许使用事件修饰符来简化事件处理逻辑,修饰符用于控制事件的默认行为或事件传播。

  • 常见修饰符
    • .prevent:调用 event.preventDefault(),阻止事件的默认行为。
    • .stop:调用 event.stopPropagation(),阻止事件的冒泡。
    • .once:事件只会触发一次,然后自动移除事件监听器。
    • .capture:在捕获阶段触发事件,而非冒泡阶段。
<template>
  <form @submit.prevent="handleSubmit">提交</form>
  <button @click.stop="handleClick">点击我</button>
</template>

<script>
export default {
  methods: {
    handleSubmit() {
      console.log("表单提交");
    },
    handleClick() {
      console.log("按钮被点击");
    }
  }
};
</script>
  • 原理
    • @submit.prevent 会阻止表单的默认提交行为。
    • @click.stop 会阻止事件的冒泡,防止父元素的点击事件被触发。
(5) 监听自定义事件

如果一个子组件需要触发一个事件并通知父组件,可以使用 v-on 来监听自定义事件。

子组件

<template>
  <button @click="emitCustomEvent">点击发送自定义事件</button>
</template>

<script>
export default {
  methods: {
    emitCustomEvent() {
      this.$emit("customEvent", "Hello, parent!");
    }
  }
};
</script>

父组件

<template>
  <child-component @customEvent="handleCustomEvent"></child-component>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleCustomEvent(message) {
      alert(`收到子组件消息: ${message}`);
    }
  }
};
</script>
  • 原理
    • 子组件通过 $emit 方法触发一个名为 customEvent 的事件,并传递一个消息。
    • 父组件使用 v-on@customEvent)来监听该事件,并调用 handleCustomEvent 方法处理。

3. v-on 前端的具体表现示意
(1) 基本点击事件
<template>
  <button @click="handleClick">点击我</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      alert("按钮被点击了!");
    }
  }
};
</script>
  • 表现:当按钮被点击时,弹出提示框“按钮被点击了!”
(2) 表单提交事件防止默认行为
<template>
  <form @submit.prevent="handleSubmit">
    <input type="text" v-model="inputText" />
    <button type="submit">提交</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      inputText: ""
    };
  },
  methods: {
    handleSubmit() {
      console.log("表单提交,输入的内容是:" + this.inputText);
    }
  }
};
</script>
  • 表现:点击提交按钮时,表单不会真正提交,而是通过 @submit.prevent 阻止了表单的默认行为,并在控制台打印输入的内容。
(3) 事件冒泡和停止事件传播
<template>
  <div @click="parentClick">
    <button @click.stop="childClick">点击我</button>
  </div>
</template>

<script>
export default {
  methods: {
    parentClick() {
      console.log("父级元素被点击");
    },
    childClick() {
      console.log("子级按钮被点击");
    }
  }
};
</script>
  • 表现:点击按钮时,@click.stop 会阻止事件冒泡,只有“子级按钮被点击”会显示在控制台,而“父级元素被点击”不会触发。
(4) 监听自定义事件

父组件

<template>
  <child-component @customEvent="handleCustomEvent"></child-component>
</template>

子组件

<template>
  <button @click="emitCustomEvent">点击发送自定义事件</button>
</template>

<script>
export default {
  methods: {
    emitCustomEvent() {
      this.$emit("customEvent", "Hello, parent!");
    }
  }
};
</script>
  • 表现:点击子组件中的按钮时,父组件会监听到 customEvent 事件并弹出 “收到子组件消息: Hello, parent!”。

4. 小结
  • v-on 是 Vue 中用于绑定事件监听器的指令,可以让我们方便地监听和处理用户的事件。
  • 它支持多种事件修饰符,如 .prevent.stop.once 等,用于控制事件行为。
  • 使用简写形式 @ 可以使代码更加简洁,如 @click 代替 v-on:click
  • 通过 v-on 绑定自定义事件,子组件可以通过 $emit 向父组件传递信息,进行父子组件之间的通信。

3.7. Vue3 v-slot:原理形象讲解以及前端的具体表现示意

1. v-slot 原理讲解

在 Vue3 中,v-slot 是一个用于插槽(slot)功能的指令。插槽是 Vue 提供的一种机制,它允许父组件向子组件传递内容。v-slot 用于声明和绑定插槽的内容,从而使父组件能够插入自定义内容到子组件的插槽中。

  • 原理v-slot 允许我们向子组件传递内容,同时可以访问子组件内部的某些数据。通过这种方式,父组件不仅可以插入静态内容,还可以插入动态内容和模板。

    • 具名插槽:子组件可以定义多个插槽,通过 v-slot 传递不同的内容到不同的插槽中。
    • 作用域插槽:除了传递内容,子组件还可以传递数据给父组件,父组件可以通过 v-slot 接收这些数据。
2. v-slot 的常见用法
(1) 基本用法:默认插槽

默认插槽是最简单的插槽类型,它允许父组件插入任意内容到子组件的插槽中。父组件传入的内容会在子组件的 <slot></slot> 标签的位置展示。

子组件ChildComponent.vue):

<template>
  <div>
    <slot></slot>  <!-- 默认插槽 -->
  </div>
</template>

父组件

<template>
  <ChildComponent>
    <p>这是从父组件传递的内容</p>
  </ChildComponent>
</template>
  • 原理:在这个例子中,ChildComponent 中的 <slot></slot> 会被父组件插入的内容 <p>这是从父组件传递的内容</p> 替代。父组件的内容会显示在子组件中。
(2) 具名插槽

具名插槽允许子组件定义多个插槽,父组件可以根据插槽的名称来指定不同的内容。

子组件ChildComponent.vue):

<template>
  <div>
    <slot name="header"></slot> <!-- 具名插槽 -->
    <slot></slot>               <!-- 默认插槽 -->
  </div>
</template>

父组件

<template>
  <ChildComponent>
    <template #header>
      <h1>这是标题</h1>
    </template>
    <p>这是正文内容</p>
  </ChildComponent>
</template>
  • 原理:父组件通过 #header 指定了具名插槽 header 的内容。当子组件中 <slot name="header"></slot> 被替换时,父组件传入的 <h1>这是标题</h1> 就会显示在 header 插槽中。默认插槽的内容 <p>这是正文内容</p> 会显示在 <slot></slot> 中。
(3) 作用域插槽

作用域插槽允许父组件不仅插入内容,还能访问子组件传递给插槽的动态数据。子组件可以通过 v-slot 向父组件暴露一些数据,父组件通过插槽内容访问这些数据。

子组件ChildComponent.vue):

<template>
  <div>
    <slot :message="message"></slot> <!-- 通过 v-slot 传递数据 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "来自子组件的消息"
    };
  }
};
</script>

父组件

<template>
  <ChildComponent>
    <template v-slot:default="slotProps">
      <p>{{ slotProps.message }}</p>  <!-- 使用父组件传递的数据 -->
    </template>
  </ChildComponent>
</template>
  • 原理:在 ChildComponent 中,v-slot 通过 :message="message" 向父组件暴露了 message 数据。父组件使用 v-slot:default="slotProps" 接收该数据,并通过 slotProps.message 访问和展示它。
(4) v-slot 的简写

在 Vue3 中,v-slot 可以使用简写形式。具体来说,v-slot:default 可以简写为 #defaultv-slot:header 可以简写为 #header

子组件ChildComponent.vue):

<template>
  <div>
    <slot name="header"></slot> <!-- 具名插槽 -->
    <slot></slot>               <!-- 默认插槽 -->
  </div>
</template>

父组件

<template>
  <ChildComponent>
    <template #header>
      <h1>这是标题</h1>
    </template>
    <p>这是正文内容</p>
  </ChildComponent>
</template>
  • 原理:在此例中,#headerv-slot:header 的简写,#defaultv-slot:default 的简写。简写方式使得代码更加简洁。

3. v-slot 前端的具体表现示意
(1) 默认插槽

父组件传入的内容会显示在子组件的插槽位置:

<ChildComponent>
  <p>这是从父组件传递的内容</p>
</ChildComponent>

表现

子组件内部:
<p>这是从父组件传递的内容</p>
  • 解释<p>这是从父组件传递的内容</p> 被插入到子组件中的 <slot></slot> 标签位置。
(2) 具名插槽

子组件定义多个插槽,父组件可以通过插槽名称来控制插入的内容:

<ChildComponent>
  <template #header>
    <h1>这是标题</h1>
  </template>
  <p>这是正文内容</p>
</ChildComponent>

表现

子组件内部:
<h1>这是标题</h1>  <!-- 来自 header 插槽 -->
<p>这是正文内容</p>  <!-- 来自默认插槽 -->
  • 解释<h1>这是标题</h1> 被插入到子组件中的 header 插槽位置,<p>这是正文内容</p> 被插入到默认插槽位置。
(3) 作用域插槽

父组件可以访问子组件暴露的数据并进行动态渲染:

<ChildComponent>
  <template v-slot:default="slotProps">
    <p>{{ slotProps.message }}</p>
  </template>
</ChildComponent>

表现

子组件内部:
<p>来自子组件的消息</p>  <!-- 通过作用域插槽传递的数据 -->
  • 解释:子组件通过 v-slot 向父组件暴露了 message 数据,父组件通过 slotProps.message 访问并展示该数据。

4. 小结
  • v-slot 是 Vue 中实现插槽功能的指令,可以让父组件向子组件传递内容。
  • 支持 默认插槽具名插槽作用域插槽,可以在父组件插入内容的同时访问子组件的数据。
  • 使用 v-slot,父组件不仅可以插入静态内容,还可以插入动态内容和模板,子组件可以向父组件传递数据,从而实现更加灵活和可组合的组件设计。
  • Vue3 中支持 v-slot 的简写方式,使代码更加简洁。

3.8. Vue3 v-pre:原理形象讲解以及前端的具体表现示意

1. v-pre 原理讲解

在 Vue3 中,v-pre 是一个特殊的指令,用于跳过当前元素及其子元素的编译过程。它告诉 Vue 在编译模板时,不要解析这个元素及其子元素的模板内容。这个指令非常有用,当你想保留模板原样渲染而不进行解析时,使用 v-pre 可以提高性能,尤其是在静态内容的情况下。

  • 原理

    • 默认情况下,Vue 会在模板编译过程中处理所有标签(如 {{ }} 插值表达式、v-ifv-for 等),并将它们转化为渲染函数。这样会消耗额外的时间和资源。
    • 当使用 v-pre 时,Vue 会跳过指定元素及其子元素的编译过程,直接渲染它们为普通的 HTML 元素。这意味着 Vue 不会为这些元素处理模板指令或插值表达式,它们会原封不动地呈现出来。
  • 适用场景

    • 适用于渲染静态内容,尤其是当你需要在页面中嵌入原始 HTML 代码或需要处理大量不需要 Vue 解析的模板时,使用 v-pre 可以提高性能。

2. v-pre 的常见用法
(1) 基本用法:跳过模板编译

使用 v-pre 指令,你可以将 Vue 忽略掉的模板内容直接展示出来,而不会进行编译和解析。

<template>
  <div v-pre>
    <p>{{ message }}</p>  <!-- 不会被解析为插值表达式 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello, Vue!"
    };
  }
};
</script>
  • 原理:使用 v-pre 后,<p>{{ message }}</p> 会被原样输出,Vue 不会对其中的 {{ message }} 进行解析,而是直接显示文字 {{ message }}。这是因为 v-pre 跳过了该部分内容的编译。
(2) 渲染原始 HTML 内容

如果你有一个需要展示原始 HTML 内容(例如,包含 HTML 标签或 Vue 模板语法的字符串),你可以使用 v-pre 跳过该部分的解析。

<template>
  <div v-pre>
    <p>{{ message }}</p>
    <p><strong>这是静态 HTML 内容</strong></p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "<strong>Vue 不会解析这个内容</strong>"
    };
  }
};
</script>
  • 原理v-pre 跳过了 {{ message }} 这一插值表达式的解析,直接渲染为字符串 {{ message }},而 强制加粗 文字不会被 Vue 解析为 HTML 标签,而是直接显示文本内容。
(3) 用于优化性能

v-pre 通常用于静态内容或原样展示的场景,可以显著提高 Vue 的渲染效率。特别是当你有大量的内容需要渲染时,跳过 Vue 的编译过程可以减少不必要的计算和渲染。

<template>
  <div v-pre>
    <p>这是一些静态文本,Vue 不会做任何解析</p>
    <p>{{ someDynamicText }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      someDynamicText: "此内容由 Vue 解析"
    };
  }
};
</script>
  • 原理v-pre 用于 p 元素,表示该元素中的文本不会进行 Vue 解析,直接渲染出原始文本。因此,{{ someDynamicText }} 被渲染为 {{ someDynamicText }},而不会插入 Vue 数据。

3. v-pre 前端的具体表现示意
(1) 默认行为:插值表达式被解析

在没有使用 v-pre 的情况下,Vue 会解析模板中的插值表达式并显示其值:

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

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

表现

Hello, Vue!
  • 解释:Vue 解析了插值表达式 {{ message }} 并显示了 message 的值。
(2) 使用 v-pre 跳过插值表达式解析

当你在模板中使用 v-pre 时,Vue 会跳过插值表达式的解析,直接原样渲染内容:

<template>
  <div v-pre>
    <p>{{ message }}</p>
  </div>
</template>

表现

{{ message }}
  • 解释{{ message }} 被原样渲染,Vue 不会对它进行解析。
(3) 用 v-pre 渲染原始 HTML 内容

如果你需要原样渲染 HTML 内容而不进行解析,v-pre 可以让你避免 Vue 解析内容:

<template>
  <div v-pre>
    <p><strong>这是静态 HTML 内容</strong></p>
  </div>
</template>

表现

<strong>这是静态 HTML 内容</strong>
  • 解释:这段 HTML 被渲染为原始 HTML 内容,不会被 Vue 解析为带有 <strong> 标签的文本。v-pre 保持了模板中的原始 HTML 结构。

4. 小结
  • v-pre 是一个用于跳过模板编译的指令。它告诉 Vue 不解析某个元素及其子元素的内容,直接渲染原始内容。
  • 使用 v-pre 可以提高性能,特别是当你需要渲染大量静态内容或原始 HTML 时。它会跳过插值表达式、指令等的解析,直接渲染为文本。
  • 适用于需要显示原始模板或静态 HTML 内容的场景,避免不必要的 Vue 编译和解析。

注意事项:虽然 v-pre 可以提高性能,但它只适用于静态内容,不适合用于动态内容或需要绑定数据的场景。在这种情况下,应该避免使用 v-pre

3.9. Vue3 v-once:原理形象讲解以及前端的具体表现示意

1. v-once 原理讲解

在 Vue3 中,v-once 是一个指令,用于使某个元素或组件只渲染一次。它告诉 Vue 只在首次渲染时编译和渲染元素或组件,之后将元素或组件缓存下来,任何后续的数据变化都不会重新渲染该元素或组件。v-once 适用于那些内容固定、不需要响应式更新的部分,能提高性能,减少不必要的渲染。

  • 原理:在 Vue 的渲染过程中,当使用 v-once 时,Vue 会把元素或组件的 HTML 标记在第一次渲染时缓存起来。后续的数据变化不会导致这些元素或组件的重新渲染,因为它们已经被视为“静态”的。
  • 适用场景v-once 适用于不会变化的内容(例如,静态的页眉、页脚、标题等),而不适用于需要响应式更新的数据。

2. v-once 的常见用法
(1) 基本用法:仅渲染一次

使用 v-once 可以确保某个部分只渲染一次,不会随着数据的变化而重新渲染。

<template>
  <div>
    <h1 v-once>这是静态内容,只渲染一次</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "这是动态内容"
    };
  }
};
</script>
  • 原理:在这个例子中,<h1> 元素会在第一次渲染时被渲染,并且之后即使 message 改变,<h1> 元素也不会重新渲染。<p> 元素会随着 message 的变化而更新。
(2) 用于组件的静态渲染

如果某个组件内容在首次渲染后不再变化,可以通过 v-once 来提高性能。

<template>
  <div>
    <StaticComponent v-once></StaticComponent>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import StaticComponent from './StaticComponent.vue';

export default {
  components: {
    StaticComponent
  },
  data() {
    return {
      message: "动态内容"
    };
  }
};
</script>
  • 原理:在这个例子中,StaticComponent 组件会在第一次渲染时被渲染,之后不再重新渲染。<p> 元素会随着 message 的变化而更新,但 StaticComponent 组件保持不变。
(3) 用于大量静态内容的优化

v-once 在需要渲染大量静态内容的场景中非常有用,可以显著提高性能,避免不必要的重新渲染。

<template>
  <div v-once>
    <p>这是静态内容,永远不会被重新渲染</p>
    <p>这里是另一个静态段落</p>
  </div>
</template>
  • 原理:所有包裹在 v-once 的元素会在第一次渲染时生成,并且不会再重新渲染,不管数据如何变化。

3. v-once 前端的具体表现示意
(1) 静态内容的首次渲染
<template>
  <h1 v-once>这是静态内容,只渲染一次</h1>
  <p>{{ message }}</p>
</template>

<script>
export default {
  data() {
    return {
      message: "这是动态内容"
    };
  }
};
</script>

表现

  • message = "这是动态内容" 时,<h1> 会显示“这是静态内容,只渲染一次”。
  • 即使 message 改变为其他值,<h1> 始终保持不变。
  • message 的变化会更新 <p> 标签中的内容。
(2) 组件的静态渲染
<template>
  <div>
    <StaticComponent v-once></StaticComponent>
    <p>{{ message }}</p>
  </div>
</template>

表现

  • StaticComponent 会在第一次渲染时显示,并且永远不会被重新渲染,即使 message 发生变化。
  • <p>{{ message }}</p> 会随着 message 的变化而更新。
(3) 用于静态内容的性能优化
<template>
  <div v-once>
    <p>这是静态内容,永远不会被重新渲染</p>
    <p>这里是另一个静态段落</p>
  </div>
</template>

表现

  • <p>这是静态内容,永远不会被重新渲染</p><p>这里是另一个静态段落</p> 会在第一次渲染时显示,并且后续不会再重新渲染,不论数据如何变化。

4. 小结
  • v-once 是一个性能优化指令,用于将某个元素或组件的渲染过程限制为只执行一次,之后的数据变化不会引起该元素或组件的重新渲染。
  • 它适用于那些 静态内容静态组件,即它们的内容在整个生命周期内不会发生变化。
  • 在大量静态内容或大量不变的组件中,使用 v-once 可以减少不必要的渲染,提高性能,尤其在大型应用中非常有效。
  • 注意v-once 不适用于需要响应式更新的动态内容。如果你希望某部分内容保持响应式,应该避免使用 v-once

性能提示:使用 v-once 时,Vue 会跳过该元素或组件的后续更新,因此仅适用于不需要响应式更新的静态内容。

3.10. Vue3 v-text:原理形象讲解以及前端的具体表现示意

1. v-text 原理讲解

在 Vue3 中,v-text 是一个指令,用于将元素的 文本内容 设置为某个动态值,并直接更新文本内容。它是 Vue 提供的一个简化版的绑定方式,主要用于 设置元素的文本内容,替代 {{ expression }} 的插值表达式语法。

  • 原理:当你使用 v-text 时,Vue 会将指令绑定的值作为文本插入到元素中,并且会在值发生变化时,更新该文本内容。与 {{ expression }} 不同的是,v-text直接 将内容插入到元素的 文本节点,而不会解析为 HTML。

  • 适用场景v-text 适用于需要动态更新文本内容的场景。它比插值表达式({{ }})更简洁,且避免了不必要的 DOM 更新。v-text 只处理文本内容,不支持解析 HTML 标签(如果你需要插入 HTML 内容,应使用 v-html)。


2. v-text 的常见用法
(1) 基本用法:直接替换元素文本

使用 v-text 可以将元素的文本内容与 Vue 数据进行绑定,动态更新文本。

<template>
  <div>
    <h1 v-text="message"></h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello, Vue!"
    };
  }
};
</script>
  • 原理v-text="message" 会将 message 的值(“Hello, Vue!”)插入到 <h1> 元素中。如果 message 发生变化,Vue 会自动更新 <h1> 元素中的文本内容。
(2) 动态更新文本内容

当数据发生变化时,v-text 会自动更新文本内容。

<template>
  <div>
    <h1 v-text="message"></h1>
    <button @click="changeMessage">更改消息</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "初始消息"
    };
  },
  methods: {
    changeMessage() {
      this.message = "消息已更新!";
    }
  }
};
</script>
  • 原理:在此例中,当点击按钮时,message 会发生变化,v-text 会将 message 的新值 “消息已更新!” 更新到 <h1> 元素中。
(3) 比较 v-text 与插值表达式

使用 v-text 与插值表达式({{ }})的效果相似,区别在于 v-text 直接绑定文本内容,而插值表达式会解析为 HTML 内容。

<template>
  <div>
    <h1 v-text="message"></h1>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello, <strong>Vue!</strong>"
    };
  }
};
</script>
  • 原理:在这个例子中,v-text 会将 message 的值 “Hello, Vue!” 作为文本插入到 <h1> 元素中,HTML 标签(如 <strong>)会被原样显示。而插值表达式 {{ message }} 会将其解析并渲染 HTML,显示出加粗文本 “Vue!”。

3. v-text 前端的具体表现示意
(1) 基本用法:动态替换文本内容
<template>
  <h1 v-text="message"></h1>
</template>

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

表现

  • <h1> 元素会渲染为:

    Hello, Vue!
    
  • message 的值发生变化时(例如,message = "Vue is awesome!"),<h1> 元素会自动更新为新的文本内容。

(2) 更新文本内容
<template>
  <div>
    <h1 v-text="message"></h1>
    <button @click="changeMessage">更改消息</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "初始消息"
    };
  },
  methods: {
    changeMessage() {
      this.message = "消息已更新!";
    }
  }
};
</script>

表现

  • 初始渲染时,<h1> 中显示 初始消息
  • 点击按钮后,message 变为 "消息已更新!",然后 <h1> 中的文本更新为 "消息已更新!"
(3) 与插值表达式的差异
<template>
  <div>
    <h1 v-text="message"></h1>
    <h1>{{ message }}</h1>
  </div>
</template>

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

表现

  • 使用 v-text 时,<h1> 中的文本显示为:

    Hello, <strong>Vue!</strong>
    
  • 使用插值表达式时,<h1> 会显示:

    Hello, Vue!
    

    其中 <strong> 标签会被解析并应用样式,显示为加粗的 “Vue!”。

(4) 性能优化

v-text 可以减少模板的计算量,特别是在动态更新文本时,它仅更新文本节点而不是重新渲染整个组件或元素。

<template>
  <div>
    <p v-text="content"></p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      content: "这是一段动态更新的文本"
    };
  }
};
</script>

表现

  • 初始渲染时,<p> 会显示 "这是一段动态更新的文本"
  • content 改变时,<p> 会立即更新为新的文本内容,减少了不必要的 DOM 操作。

4. 小结
  • v-text 是 Vue 中用于绑定元素文本内容的指令。它将动态数据绑定到元素的 文本节点,并在数据变化时自动更新。
  • 使用 v-text 可以替代插值表达式({{ }}),并且不会将文本解析为 HTML 标签,因此适用于纯文本更新。
  • 优点:简洁、直接,特别适合动态更新文本内容时,避免不必要的 DOM 更新。
  • 注意事项v-text 仅限于文本内容的更新,如果需要插入 HTML 内容,应使用 v-html

3.11. Vue3 v-html:原理形象讲解以及前端的具体表现示意

1. v-html 原理讲解

在 Vue3 中,v-html 是一个指令,用于将动态内容作为 HTML 插入到元素中。它可以将模板中绑定的内容 解析为 HTML 标签,并将这些标签渲染到页面中。与 v-text 不同,v-html 会处理 HTML 标签,而不是将其作为纯文本渲染。

  • 原理:当你使用 v-html 时,Vue 会将指定的数据解析为 HTML 字符串,并将这些 HTML 内容直接插入到 DOM 中。这样,所有的标签(如 <div>, <p>, <strong>, <a> 等)会被解析为实际的 HTML 元素,并且会按照 HTML 规则渲染。

  • 适用场景v-html 适用于需要将 HTML 内容插入到元素中的场景,例如动态生成的 HTML 或从后端 API 获取的 HTML 字符串。


2. v-html 的常见用法
(1) 基本用法:将 HTML 内容插入元素中

使用 v-html 可以将动态的 HTML 内容绑定到元素上。

<template>
  <div>
    <div v-html="htmlContent"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      htmlContent: "<h1>Hello, <strong>Vue!</strong></h1>"
    };
  }
};
</script>
  • 原理:在这个例子中,v-html="htmlContent" 会将 htmlContent 中的 HTML 字符串插入到 <div> 元素中。内容 "Hello, <strong>Vue!</strong>" 被解析为 <h1><strong> 标签,从而显示为加粗的 “Vue!”。
(2) 动态插入 HTML 内容

当数据变化时,v-html 会动态更新绑定的 HTML 内容。

<template>
  <div>
    <div v-html="htmlContent"></div>
    <button @click="changeContent">更新内容</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      htmlContent: "<p>初始 HTML 内容</p>"
    };
  },
  methods: {
    changeContent() {
      this.htmlContent = "<h2>新的 <em>HTML</em> 内容!</h2>";
    }
  }
};
</script>
  • 原理:初始时,htmlContent 的值为 <p>初始 HTML 内容</p>,因此 <div> 元素显示为 “初始 HTML 内容”。当点击按钮时,htmlContent 更新为 <h2>新的 HTML 内容!</h2>v-html 会重新渲染新的 HTML。
(3) 使用 v-html 显示动态生成的 HTML

如果你从 API 或其他地方获取动态的 HTML 内容,可以使用 v-html 将其直接插入页面。

<template>
  <div>
    <div v-html="dynamicHtml"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dynamicHtml: "<p>来自 API 的 <a href='#'>链接</a></p>"
    };
  },
  mounted() {
    // 模拟从 API 获取数据
    setTimeout(() => {
      this.dynamicHtml = "<p>新的内容 <a href='#'>点击这里</a></p>";
    }, 2000);
  }
};
</script>
  • 原理dynamicHtml 初始为一个包含 <p><a> 标签的 HTML 字符串。两秒后,dynamicHtml 更新,新的 HTML 内容会替换之前的内容并渲染。

3. v-html 前端的具体表现示意
(1) 基本用法:插入 HTML 内容
<template>
  <div>
    <div v-html="htmlContent"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      htmlContent: "<h1>这是 <strong>加粗</strong> 的文本</h1>"
    };
  }
};
</script>

表现

  • <h1>这是 <strong>加粗</strong> 的文本</h1> 被解析为 HTML,并在页面中渲染为加粗文本 “加粗”。
(2) 动态更新 HTML 内容
<template>
  <div>
    <div v-html="htmlContent"></div>
    <button @click="changeContent">更新内容</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      htmlContent: "<p>初始内容</p>"
    };
  },
  methods: {
    changeContent() {
      this.htmlContent = "<h2>新的 <em>HTML</em> 内容!</h2>";
    }
  }
};
</script>

表现

  • 初始时,<div> 显示 “初始内容”。
  • 点击按钮后,htmlContent 更新为 <h2>新的 HTML 内容!</h2>,然后 <div> 中的内容更新为新的 HTML 格式。
(3) 从 API 获取动态 HTML 内容
<template>
  <div>
    <div v-html="dynamicHtml"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dynamicHtml: "<p>来自 API 的 <a href='#'>链接</a></p>"
    };
  },
  mounted() {
    setTimeout(() => {
      this.dynamicHtml = "<p>新的内容 <a href='#'>点击这里</a></p>";
    }, 2000);
  }
};
</script>

表现

  • 初始时,<div> 中会显示 <p>来自 API 的 <a href='#'>链接</a></p>,即带有一个超链接的段落。
  • 两秒钟后,dynamicHtml 更新为新的 HTML 内容,<div> 中的内容更新为新的 <p> 标签和超链接。

4. v-html 的注意事项
  • XSS(跨站脚本攻击)风险:使用 v-html 时,需要特别注意 XSS(Cross-Site Scripting) 攻击。如果插入的 HTML 内容来自不可信的来源(如用户输入或外部 API),必须小心,避免插入恶意的脚本代码。你可以使用一些安全的 HTML 过滤库,如 DOMPurify 来确保内容的安全。

  • 性能问题v-html 会重新插入 HTML 内容,这意味着每次数据更新时,都会重新渲染整个 HTML 内容。对于复杂的页面,频繁更新 HTML 内容可能会影响性能,特别是在大量动态更新时。

  • 限制v-html 只插入 HTML 内容,它不会解析 Vue 的模板语法(如 v-ifv-for 等),这些指令无法在插入的 HTML 中起作用。


5. 小结
  • v-html 是 Vue 中用于插入动态 HTML 内容的指令,它将绑定的 HTML 字符串解析并渲染为实际的 HTML 元素。
  • 优点:可以插入和渲染 HTML 内容,适用于从 API 或动态生成的 HTML 片段。
  • 注意事项
    • 要小心 XSS 攻击,避免插入恶意脚本。
    • 对于频繁更新的内容,v-html 可能带来性能问题。
    • v-html 只渲染 HTML 内容,不会解析 Vue 的模板指令。

3.12. Vue3 v-cloak:原理形象讲解以及前端的具体表现示意

1. v-cloak 原理讲解

在 Vue3 中,v-cloak 是一个用于在 Vue 实例启动之前隐藏未编译的模板代码的指令。它主要用于解决 闪烁问题,即在页面初次加载时,Vue 实例初始化之前,页面上可能会短暂显示出原始的模板语法(如插值表达式 {{ }})。v-cloak 通过隐藏这些未编译的部分,直到 Vue 实例完成初始化,确保用户只看到渲染后的内容。

  • 原理:当你在某个元素上使用 v-cloak 时,Vue 会在页面加载时隐藏包含该指令的元素,直到 Vue 实例初始化完成并且数据绑定等操作已经完成。此时,Vue 会移除 v-cloak,并开始渲染和显示内容。

  • 适用场景v-cloak 适用于需要防止页面闪烁或显示未解析的 Vue 模板语法的场景,尤其是当 Vue 实例挂载到页面时,模板内容还未完全渲染出来时。


2. v-cloak 的常见用法
(1) 基本用法:隐藏 Vue 模板语法

通常,在模板中使用 v-cloak 来隐藏 Vue 模板中的未编译部分,直到 Vue 完成初始化。

<template>
  <div id="app" v-cloak>
    <h1>{{ message }}</h1>
  </div>
</template>

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

<style>
[v-cloak] {
  display: none;
}
</style>
  • 原理:在页面加载时,v-cloak 会让包含 v-cloak 的元素(即 <div id="app">)在 Vue 完成初始化前保持 display: none。当 Vue 完成挂载并渲染内容时,v-cloak 会被移除,页面上会显示绑定的数据。
(2) 用于避免闪烁效果

当页面还没有加载完成时,如果直接显示包含 Vue 语法的模板,用户可能会看到未解析的 Vue 语法(如 {{ message }})。使用 v-cloak 可以避免这种闪烁现象。

<template>
  <div id="app" v-cloak>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "正在加载..."
    };
  }
};
</script>

<style>
[v-cloak] {
  display: none;
}
</style>
  • 原理:页面加载时,由于使用了 v-cloak,在 Vue 初始化完成之前,页面中的 {{ message }} 不会显示出来。直到 Vue 完成模板编译并渲染后,v-cloak 被移除,用户才看到正确的内容。
(3) 用于大型应用或延迟加载时的防闪烁

对于大型应用或需要延迟加载的 Vue 组件,可以使用 v-cloak 来避免在 Vue 加载之前显示原始模板内容。

<template>
  <div id="app" v-cloak>
    <h1>{{ message }}</h1>
    <p v-if="loaded">加载完成!</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "正在加载数据...",
      loaded: false
    };
  },
  mounted() {
    setTimeout(() => {
      this.message = "数据加载完毕!";
      this.loaded = true;
    }, 2000);
  }
};
</script>

<style>
[v-cloak] {
  display: none;
}
</style>
  • 原理:在数据加载时,v-cloak 保证了页面在 Vue 初始化和数据加载完成之前不会闪烁出未解析的 Vue 模板。直到 mounted 钩子内的代码执行并更新数据,v-cloak 才会被移除。

3. v-cloak 前端的具体表现示意
(1) 页面初始加载时使用 v-cloak 隐藏模板内容
<template>
  <div id="app" v-cloak>
    <h1>{{ message }}</h1>
  </div>
</template>

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

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

表现

  • 初始加载时,<div id="app"> 内的内容不会显示,用户会看到一个空白区域,因为 v-cloak 会将它的内容隐藏(display: none)。
  • 当 Vue 初始化完成并渲染数据时,v-cloak 会被移除,{{ message }} 会被动态绑定成 "Hello, Vue!",并显示到页面上。
(2) 用于数据加载时避免显示未解析内容
<template>
  <div id="app" v-cloak>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "正在加载..."
    };
  },
  mounted() {
    setTimeout(() => {
      this.message = "数据加载完毕!";
    }, 2000);
  }
};
</script>

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

表现

  • 页面在加载时不会显示 "正在加载...",而是一个空白区域,直到 Vue 完成初始化并渲染数据。
  • message 更新后,v-cloak 被移除,页面显示 "数据加载完毕!"
(3) 用于防止在 Vue 完全加载前显示 Vue 模板语法
<template>
  <div v-cloak>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "加载中..."
    };
  }
};
</script>

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

表现

  • 在页面加载时,v-cloak 会防止页面显示原始的 Vue 模板语法 {{ message }},从而避免了用户看到模板语法,直到 Vue 完成初始化并渲染。

4. 小结
  • v-cloak 是一个特殊指令,用于防止在 Vue 完成初始化之前显示未编译的模板内容。它通过为包含该指令的元素添加 display: none 样式,确保这些内容在页面加载时不会显示。
  • 优点:可以避免 页面闪烁显示未解析的 Vue 模板语法,提高用户体验,尤其是在大型应用或延迟加载的场景中。
  • 使用场景:适用于需要隐藏模板代码直到 Vue 完成初始化的场景,尤其是在页面初始加载时,避免显示未渲染的 Vue 数据或指令。

注意v-cloak 只适用于 Vue 初始化过程中的防闪烁效果,并不影响 Vue 实例的其他功能。

3.13. Vue3 v-memo:原理形象讲解以及前端的具体表现示意

1. v-memo 原理讲解

在 Vue3 中,v-memo 是一个优化性能的指令,允许开发者 显式地标记某些元素和组件 为 “记忆化” 的,即只在它们的依赖发生变化时才重新渲染。v-memo 可以帮助提高性能,特别是在处理不常变化的部分时,避免不必要的重新渲染。

  • 原理v-memo 通过指定 依赖数组,在 Vue 渲染时检查某个元素或组件的依赖是否发生变化。如果依赖没有发生变化,Vue 会跳过重新渲染该元素或组件,而直接复用之前渲染的结果。这种优化机制能够显著减少不必要的渲染,尤其是对于复杂的组件或大量动态更新的数据,能够大幅提高性能。

  • 适用场景v-memo 适用于那些 稳定性高不需要频繁更新 的部分,尤其是在大规模应用中,或者当你有大量的静态内容和少量的动态内容时,使用 v-memo 可以显著减少渲染开销。


2. v-memo 的常见用法
(1) 基本用法:标记部分为记忆化

使用 v-memo 来标记一个元素或组件,当它的依赖不发生变化时,Vue 会跳过该部分的重新渲染。

<template>
  <div>
    <h1>{{ message }}</h1>
    <div v-memo="[message]">
      <p>这是一个需要记忆化的内容</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello, Vue!"
    };
  }
};
</script>
  • 原理:在这个例子中,v-memo="[message]" 表示只有 message 数据发生变化时,包裹在 <div> 中的内容才会重新渲染。如果 message 不发生变化,则该部分的渲染会被记忆下来,不会重新渲染。
(2) 在大规模应用中优化性能

在较大规模的应用中,可能存在一些组件或部分内容是相对静态的,不需要随着数据的变化频繁更新。在这种情况下,使用 v-memo 可以减少不必要的渲染。

<template>
  <div>
    <h1>{{ title }}</h1>
    <div v-memo="[title]">
      <p>这是一个不会频繁更新的静态内容</p>
    </div>
    <button @click="updateTitle">更改标题</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: "静态内容"
    };
  },
  methods: {
    updateTitle() {
      this.title = "标题已更新!";
    }
  }
};
</script>
  • 原理v-memo="[title]" 表示如果 title 没有变化,包裹在 <div> 中的内容就不会重新渲染,即使数据的其他部分发生变化也不影响该部分的渲染。
(3) 在组件中使用 v-memo

如果你有一个组件,其中有某些部分是不会频繁更新的,可以使用 v-memo 来优化性能。

<template>
  <div>
    <ChildComponent v-memo="[message]" :message="message" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  data() {
    return {
      message: "Hello from parent"
    };
  }
};
</script>
  • 原理:在这个例子中,ChildComponent 组件只有当 message 数据发生变化时才会重新渲染其内部内容。如果 message 没有变化,Vue 会跳过重新渲染该组件。

3. v-memo 前端的具体表现示意
(1) 基本用法:只有依赖变化时才重新渲染
<template>
  <div>
    <h1>{{ message }}</h1>
    <div v-memo="[message]">
      <p>这是一个静态内容,不会频繁更新</p>
    </div>
    <button @click="changeMessage">更改消息</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "初始消息"
    };
  },
  methods: {
    changeMessage() {
      this.message = "消息已更新!";
    }
  }
};
</script>

表现

  • 页面初始时,message"初始消息"<p> 中显示 "这是一个静态内容,不会频繁更新"
  • 当点击按钮更新 message 后,v-memo 使得只有 message 更新时,<div> 内的静态内容才会重新渲染。若没有 v-memo,即使 message 改变,<p> 也会被重新渲染。
(2) 优化大型应用中的静态内容
<template>
  <div>
    <h1>{{ title }}</h1>
    <div v-memo="[title]">
      <p>这是不会频繁更新的部分</p>
    </div>
    <button @click="changeTitle">更新标题</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: "静态标题"
    };
  },
  methods: {
    changeTitle() {
      this.title = "新的标题";
    }
  }
};
</script>

表现

  • title 改变时,只有 <h1>{{ title }}</h1> 会更新,而 <p> 内容不会重新渲染,保持静态。
  • 这样即使 title 更新,<div v-memo> 中的内容就不会被重新渲染,提升了性能。
(3) 在复杂组件中减少不必要的渲染
<template>
  <div>
    <ComplexComponent v-memo="[data]" :data="data" />
  </div>
</template>

<script>
import ComplexComponent from './ComplexComponent.vue';

export default {
  data() {
    return {
      data: "复杂数据"
    };
  }
};
</script>

表现

  • 只要 data 没有发生变化,ComplexComponent 就不会重新渲染,避免了组件中静态内容的重复渲染,减少性能消耗。

4. 小结
  • v-memo 是一个性能优化指令,允许开发者显式地标记元素或组件,在其依赖数据不发生变化时跳过重新渲染。
  • 优点
    • 避免不必要的渲染,减少性能开销。
    • 特别适用于有大量静态内容的场景,或者当某些部分的数据很少变化时。
    • 适用于 组件元素,如果它们的依赖没有变化,可以避免重复渲染。
  • 注意事项
    • v-memo 适合静态内容的优化,对于动态更新频繁的内容,不建议使用 v-memo
    • 依赖数组中的变量必须合理,确保仅在依赖项变化时触发渲染。

总结v-memo 适合用于减少不必要的渲染,优化性能,特别是在大型应用和静态内容较多的场景下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值