Bootstrap

Vue3视图渲染技术

目录

1. 模版语言

1.1 插值表达式和文本渲染

1.2 Attribute属性渲染

1.3 事件的绑定

2. 响应式基础

2.1 响应式实现关键字ref

2.2 响应式实现关键字reactive

2.3 toRef 函数和 reactive 函数(了解)

3. 条件和列表渲染

3.1 条件渲染

3.2 列表渲染

4. 双向绑定

4.1 单项绑定和双向绑定

4.2 v-model指令

4.3 常见使用场景

5. 属性计算

6. 数据监听器

6.1 数据监听器概述

6.2 watch选项

6.3 异步操作与额外逻辑


1. 模版语言

Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。

1.1 插值表达式和文本渲染

定义与简介:插值表达式是模版语言中的一种语法,用于在HTML中插入动态的内容或变量。它允许我们将数据绑定到页面上,实现动态渲染。简单来说,插值表达式就是将变量或表达式的值插入到HTML文本中。

基础用法:在HTML中使用插值表达式进行文本渲染的示例代码如下:

<div>{{ message }}</div>

这里的 message 是一个变量,其值将会被动态插入到 <div> 元素中。

高级用法:在插值表达式中,可以使用JavaScript表达式来进行更加复杂的操作,例如:

<div>{{ isTrue ? 'Yes' : 'No' }}</div>

这里的 isTrue 是一个JavaScript表达式,根据条件的真假来动态渲染文本内容。

1.2 Attribute属性渲染

动态属性绑定:模版语言允许动态地绑定HTML元素的属性,例如:

<a v-bind:href="url">Link</a>

这里的 v-bind:href 指令表示将链接的 href 属性与 url 变量进行动态绑定,从而实现动态链接地址。

 v-bind指令:v-bind 是模版语言中用于动态绑定属性的指令,其简写形式为 :。上述示例中的 v-bind:href 可以简写为 :href

布尔属性处理:有时需要根据条件来动态添加或移除布尔类型的属性,例如:

<input type="checkbox" v-bind:checked="isChecked">

这里的 v-bind:checked 指令将根据 isChecked 变量的真假来动态设置或移除 checked 属性。 

1.3 事件的绑定

事件绑定概述:事件绑定用于在模版语言中将特定的事件与页面上的元素进行关联,以便实现交互操作和用户响应。

v-on指令:v-on 是模版语言中用于绑定事件的指令,其简写形式为 @。例如,可以这样绑定点击事件:

<button v-on:click="handleClick">Click me</button>

事件处理方法:定义和调用事件处理方法的示例代码如下:

<script>
  new Vue({
    methods: {
      handleClick: function() {
        // 处理点击事件的逻辑
      }
    }
  });
</script>

通过模版语言的插值表达式和文本渲染、Attribute属性渲染以及事件的绑定,可以实现动态渲染页面内容、绑定属性和处理用户交互,从而为用户提供更加丰富和动态的用户体验。 


2. 响应式基础

响应式是指 : 数据模型发生变化时,自动更新DOM树内容,页面上显示的内容会进行同步变化,vue3的数据模型不是自动响应式的,需要我们做一些特殊的处理

2.1 响应式实现关键字ref

ref的定义:在Vue 3中,ref是一个用于创建响应式数据的关键字。它可以将普通的数据转换为响应式数据,并返回一个包含该数据的引用。ref是Vue 3中最基本的响应式实现方式之一。

创建与使用:以下是创建ref对象并访问其值的示例代码:

import { ref } from 'vue';

const count = ref(0); // 创建一个包含数字0的ref对象
console.log(count.value); // 访问ref对象的值,输出0

在上述示例中,我们使用ref函数来创建一个包含数字0的ref对象,并通过.value来访问其值。

模版中的应用:在Vue 3的模板中,可以使用ref对象来访问其值,例如:

<p>{{ count }}</p>

 在模板中直接使用{{ count }}来显示ref对象的值。

2.2 响应式实现关键字reactive

reactive的定义:reactive是另一种用于创建响应式数据的关键字。与ref不同,reactive用于创建包含多个属性的响应式对象,并返回一个包含这些属性的响应式代理对象。

创建复杂数据结构:以下是使用reactive创建响应式对象和数组的示例代码:

import { reactive } from 'vue';

const state = reactive({
  count: 0,
  message: 'Hello',
  list: [1, 2, 3]
});

在上述示例中,我们使用reactive函数创建了一个包含多个属性的响应式对象state,其中包括countmessagelist

模版中的应用:在模板中可以直接访问reactive对象的属性,例如:

<p>{{ state.count }}</p>
<ul>
  <li v-for="item in state.list" :key="item">{{ item }}</li>
</ul>

在模板中使用state.count来访问reactive对象中的count属性,并使用v-for指令遍历list数组。 

2.3 toRef 函数和 reactive 函数(了解)

toRef函数:toRef函数用于将一个响应式对象的属性转换为一个ref对象。这在需要将响应式数据作为props传递给子组件时非常有用,因为子组件可能需要对props进行修改,而props本身是只读的。以下是toRef函数的示例用法:

import { reactive, toRef } from 'vue';

const state = reactive({
  count: 0,
  message: 'Hello'
});

const countRef = toRef(state, 'count'); // 将state对象中的count属性转换为ref对象

嵌套reactive对象:reactive函数不仅可以创建简单的响应式对象,还可以创建嵌套的响应式对象。这在处理复杂的数据结构时非常有用,例如:

const nestedState = reactive({
  nested: {
    count: 0
  }
});

在上述示例中,我们使用reactive函数创建了一个嵌套的响应式对象nestedState,其中包含了nested对象和其内部的count属性。 


3. 条件和列表渲染

3.1 条件渲染

条件渲染概述: 条件渲染是指根据特定条件来决定是否渲染或显示特定的内容,这在Vue应用中非常常见,比如根据用户登录状态显示不同的界面、根据数据是否存在来展示不同的信息等。

v-if指令: v-if指令是Vue中用于条件渲染的指令,它根据表达式的真假来决定是否渲染DOM元素。如果表达式为真,则元素会被渲染;如果表达式为假,则元素不会被渲染。示例如下:

<p v-if="isUserLoggedIn">Welcome, User!</p>

在上面的例子中,如果isUserLoggedIn为true,那么段落元素会被渲染出来;如果isUserLoggedIn为false,那么段落元素不会被渲染。

v-else和v-else-if指令: 除了v-if,Vue还提供了v-else和v-else-if指令来处理更复杂的条件渲染逻辑。示例如下:

<div v-if="type === 'A'">
  Type A
</div>
<div v-else-if="type === 'B'">
  Type B
</div>
<div v-else>
  Other Types
</div>

在上面的例子中,根据变量type的不同取值,会渲染出不同的内容。如果type为'A',则会显示"Type A";如果type为'B',则会显示"Type B";否则会显示"Other Types"。

3.2 列表渲染

列表渲染概述: 列表渲染是指根据数据的内容来动态生成多个相似的元素,比如根据数据数组生成多个列表项、根据对象的属性生成多个卡片等。

v-for指令: v-for指令是Vue中用于列表渲染的指令,它可以遍历数组或对象,并根据其中的每个元素生成对应的DOM元素。示例如下

<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>

在上面的例子中,v-for指令遍历了名为items的数组,对数组中的每个元素生成一个li元素,并显示每个元素的name属性。

key属性的重要性: 在使用v-for进行列表渲染时,每个生成的DOM元素都需要有一个唯一的key属性,这样Vue才能更高效地更新DOM。key属性帮助Vue识别每个节点,并在数据发生变化时准确地重新渲染页面,以避免出现错误的DOM更新。示例如下:

<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>

在上面的例子中,:key="item.id"指定了每个li元素的唯一标识,确保在列表发生变化时Vue能够正确地更新DOM。


4. 双向绑定

4.1 单项绑定和双向绑定

单项绑定

定义: 单项绑定是指数据从模型(Model)流向视图(View),视图根据模型中的数据进行更新,但视图的变化不会反馈回模型。这种绑定方式在传统的前端框架中很常见,比如React。

特点:

  1. 数据流向单一: 只允许数据从模型流向视图,确保数据流动的方向性和可控性。
  2. 易于调试: 由于数据流动方向单一,调试过程中可以更容易地追踪数据的来源和去向。
  3. 性能优势: 在某些情况下,单项绑定可以提高性能,因为它避免了不必要的数据更新。

示例: 

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { message: 'Hello, World!' };
  }

  render() {
    return <p>{this.state.message}</p>;
  }
}

在这个例子中,state中的message属性通过单项绑定传递给视图。当state中的数据变化时,视图会相应更新,但视图中的修改不会反过来影响state

双向绑定

定义: 双向绑定是指数据在模型和视图之间双向流动,模型中的数据更新会自动反映到视图中,而用户在视图中的操作也会自动更新模型中的数据。这种绑定方式在Vue和Angular等框架中常见。

特点:

  1. 数据同步: 模型和视图之间的数据能够实时同步,减少手动更新的工作量。
  2. 简化表单处理: 特别适用于处理表单控件,用户输入的数据可以直接反映在模型中。
  3. 复杂性: 尽管简化了数据同步的操作,但可能会增加调试的复杂性,因为数据变化的源头不再单一。

示例: 

<div id="app">
  <input v-model="message" />
  <p>{{ message }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  }
});
</script>

总结对比

  • 数据流向:

    • 单项绑定:数据从模型到视图,单向流动。
    • 双向绑定:数据在模型和视图之间双向流动。
  • 适用场景:

    • 单项绑定:适用于数据流动方向明确、数据源和数据展示分离的场景,如React中的组件。
    • 双向绑定:适用于需要频繁交互和数据同步的场景,特别是表单控件,如Vue和Angular中的表单处理。
  • 调试难度:

    • 单项绑定:调试相对简单,数据流向明确。
    • 双向绑定:调试可能较为复杂,需要跟踪数据的双向流动。

4.2 v-model指令

v-model指令是Vue中用于实现双向绑定的关键指令。它可以用于多种表单控件(如input、textarea、select等)以及自定义组件上。

使用v-model指令的语法为:v-model="dataProperty",其中dataProperty是Vue实例中的一个数据属性。

示例:

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

 在上面的例子中,通过v-model指令将输入框和Vue实例中的message属性进行了双向绑定。当用户在输入框中输入内容时,message属性会实时更新;同时,当message属性的值发生改变时,输入框中的内容也会同步更新。

4.3 常见使用场景

v-model指令在表单控件中的应用非常常见,以下是一些示例:

文本输入框:

<input type="text" v-model="username" />

复选框:

<input type="checkbox" v-model="isChecked" />

单选框:

<input type="radio" value="A" v-model="selectedOption" />
<input type="radio" value="B" v-model="selectedOption" />

下拉框:

<select v-model="selectedOption">
  <option value="A">Option A</option>
  <option value="B">Option B</option>
</select>

5. 属性计算

计算属性概述: 计算属性是Vue.js中一种非常有用的特性,用于对数据进行计算并返回一个新的值。它可以根据依赖的数据动态地计算出新的数值,而且只有在相关数据发生变化时才会重新计算。

优势:

  • 简洁明了: 计算属性让代码更加清晰和易于维护,将数据的计算逻辑从模板中抽离出来,使得模板更加简洁易懂。
  • 响应式更新: 计算属性会自动追踪依赖的数据,并在相关数据发生变化时自动更新,无需手动处理数据变化的逻辑。
  • 缓存机制: 计算属性具有缓存机制,避免了不必要的重复计算,从而提高了性能。

computed选项

在Vue.js组件中,可以使用computed选项来定义计算属性,以便于对数据进行计算并返回结果。

new Vue({
  data: {
    radius: 5
  },
  computed: {
    area() {
      return Math.PI * this.radius * this.radius;
    }
  }
});

在上面的示例中,area被定义为一个计算属性,它根据radius的值动态计算出圆的面积。在模板中可以直接引用area属性,而不需要在模板中编写复杂的计算逻辑。

缓存机制

解释计算属性的缓存机制及其带来的性能优势: 计算属性具有缓存机制,即只有在相关依赖发生改变时才会重新计算。这意味着无论计算属性被多次访问,只要相关依赖数据没有发生变化,它都会立即返回之前缓存的计算结果,而不会重新执行计算逻辑。

这种缓存机制带来了以下性能优势:

  • 避免重复计算: 当依赖数据没有变化时,计算属性会直接返回之前缓存的结果,避免了不必要的重复计算。
  • 响应式更新: 计算属性依赖的数据发生变化时,缓存会被清除,计算属性会重新计算并返回新的结果,从而实现了响应式更新。

通过缓存机制,计算属性能够在保证数据计算的准确性的同时提高性能,特别是在处理复杂的计算逻辑或大量数据时,能够显著地提升页面的渲染效率和用户体验。


6. 数据监听器

6.1 数据监听器概述

 数据监听器是前端框架(如Vue.js)中一种重要的机制,用于监测数据变化并执行相应的逻辑。它能够有效地响应数据的变化,并在数据发生改变时执行预定的操作,比如更新视图或触发其他业务逻辑。

作用和应用场景:

  • 响应数据变化: 数据监听器能够监测到数据的变化,无论是基本数据类型还是对象、数组等复杂数据结构。
  • 执行特定逻辑: 可以在数据发生变化时执行特定的逻辑,如更新相关的DOM元素、发送网络请求、触发动画效果等。
  • 优化性能: 通过监听数据变化,可以避免全局性的数据轮询或手动检查数据变化的操作,从而提高代码的效率和性能。

 

6.2 watch选项

在Vue.js中,可以使用watch选项来定义数据监听器,以监视一个特定的数据并在其变化时执行回调函数。

// 示例:监听message属性的变化,并在变化时输出新的值
new Vue({
  data: {
    message: 'Hello, Vue!'
  },
  watch: {
    message(newValue, oldValue) {
      console.log(`message changed from ${oldValue} to ${newValue}`);
      // 可以在这里执行其他逻辑,如异步操作
    }
  }
});

在上面的示例中,当message属性的值发生变化时,会触发watch中定义的回调函数。可以在回调函数中访问到新值newValue和旧值oldValue,并且可以在此处执行任何需要的额外逻辑。

6.3 异步操作与额外逻辑

示例:

new Vue({
  data: {
    message: 'Hello, Vue!'
  },
  watch: {
    message(newValue, oldValue) {
      // 模拟异步操作,比如发送网络请求
      setTimeout(() => {
        console.log(`Async operation completed for message: ${newValue}`);
      }, 1000);
      
      // 可以在这里执行其他额外逻辑
      console.log('Additional logic executed...');
    }
  }
});

在这个示例中,当message属性的值发生变化时,首先会执行一个模拟的异步操作(例如异步请求),然后在控制台输出相应的信息。同时,也可以在watch中执行其他需要的额外逻辑,比如更新其他相关状态或界面元素。

;