24.vue3学习篇-响应式原理

1.Vue2

在 Vue 2 中,Vue.set的实现主要是为了解决在 Vue 实例创建后,向响应式对象添加新属性时,新属性无法触发视图更新的问题。

以下是对Vue.set实现原理的分析

1.响应式原理基础

在 Vue 2 中,响应式原理是通过Object.defineProperty来实现的。当一个对象被创建为响应式对象时,Vue 会遍历对象的所有属性,使用Object.defineProperty将这些属性转换为 getter 和 setter。这样,当属性被读取或设置时,Vue 可以进行依赖收集和触发更新。

2.Vue.set的作用场景

当在一个已经创建的响应式对象上添加新属性时,如果直接使用obj.newProperty = value的方式,这个新属性不会被 Vue 转换为响应式的,也不会触发视图更新。而Vue.set则可以确保新添加的属性是响应式的,并且能够触发视图更新。

3.实现步骤

1.参数处理
  • Vue.set接收三个参数:目标对象target、属性名key和属性值value
  • 首先对参数进行合法性检查,确保target是一个对象,并且不是Vue实例本身(因为 Vue 实例上的属性可以直接通过this.property = value的方式添加,并且是响应式的)。
2.判断目标对象类型
  • 如果target是数组,根据属性名key判断是要添加新的数组项还是修改现有数组项。
  • 如果是添加新的数组项,可以使用数组的splice方法,这个方法会触发数组的响应式更新。例如:target.splice(key, 1, value),这样既添加了新的数组项,又触发了视图更新。
  • 如果target是普通对象,判断新添加的属性是否已经存在于对象上。如果不存在,使用Object.defineProperty将新属性转换为响应式的。
3.响应式处理
  • 对于普通对象,使用Object.defineProperty定义新属性的 getter 和 setter。
  • 在 setter 中,触发依赖这个属性的地方进行更新。Vue 通过维护一个依赖收集系统,当响应式属性被读取时,会将当前的副作用函数(如组件的渲染函数)收集为该属性的依赖。当属性被设置时,遍历依赖列表,触发所有依赖这个属性的副作用函数进行更新。

Vue.set通过特定的方式处理向响应式对象添加新属性的情况,确保新属性也是响应式的,并且能够触发视图更新。

2.Vue3

在 Vue 3 中,可以使用以下方式来使用响应式系统:

1.使用reactive创建响应式对象
import { reactive } from 'vue';

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

// 修改响应式对象的属性
state.count++;
state.message = 'New message';

在上面的代码中,使用reactive函数将一个普通对象转换为响应式对象。对响应式对象的属性进行修改时,会自动触发依赖这个属性的地方进行更新。

2.使用ref创建响应式变量
import { ref } from 'vue';

const counter = ref(0);

// 修改响应式变量的值
counter.value++;

ref用于创建一个包含值的响应式对象,通过.value来访问和修改其值。

3.在组合式 API(Composition API)中使用响应式数据

在 Vue 3 的组合式 API 中,可以方便地组织和管理响应式数据。

<template>
  <div>
    <p>Count: {{ counter }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      message: 'Hello from reactive!',
    });

    const counter = ref(0);

    const increment = () => {
      counter.value++;
    };

    return {
      counter,
      state,
      increment,
    };
  },
};
</script>

setup函数中,可以定义响应式数据和方法,并将它们返回供模板使用。

4.响应式数据的依赖收集和自动更新

当响应式数据在模板中被使用或者在其他地方被读取时,Vue 3 会自动进行依赖收集。当响应式数据发生变化时,会自动触发依赖这个数据的地方进行更新。

例如,在上面的代码中,当counter的值发生变化时,模板中的<p>Count: {{ counter }}</p>会自动更新显示新的值。

总之,在 Vue 3 中,可以使用reactiveref来创建响应式数据,并在组件的不同部分(如模板、方法、计算属性等)中使用这些响应式数据,享受响应式系统带来的自动更新和高效性能。

3.Vue3和Vue2的区别

Vue 3 中的响应式系统与 Vue 2 中的响应式系统有以下主要不同:

1.实现方式

1.vue2:

  • 使用Object.defineProperty来实现响应式。通过遍历对象的所有属性,为每个属性添加 getter 和 setter,从而实现对属性的访问和修改的拦截。
  • 这种方式对于深层次的嵌套对象和数组,需要进行递归遍历才能实现响应式,性能开销较大。而且对于新增属性和删除属性的响应式处理较为麻烦,需要使用特殊的方法(如Vue.setVue.delete)。

2.vue3

  • 使用 ES2015 的Proxy来实现响应式。Proxy可以直接代理整个对象,拦截对象的各种操作,包括属性的读取、设置、删除,以及对对象本身的操作如in运算符等。
  • Proxy能够自动处理深层次的嵌套对象和数组,无需递归遍历,性能更好。并且对于新增属性和删除属性可以直接进行响应式处理,无需额外的方法。
2.响应式的灵活性

1.vue2:

  • 在创建响应式对象后,对对象的结构进行修改可能会导致一些问题。例如,直接添加新的属性可能不会触发响应式更新,需要使用特定的方法来处理。
  • 对于数组的响应式处理,主要是通过重写数组的一些方法(如pushpop等)来实现,对于直接通过索引修改数组元素或者修改数组的长度等操作,需要特别注意以确保响应式更新。

2.vue3

  • 更加灵活地处理对象的结构变化。可以直接添加、删除属性,并且会自动实现响应式更新。
  • 对于数组,也可以像普通对象一样进行各种操作,都能正确地触发响应式更新。
3.性能优化

1.vue2:

  • 在响应式数据较多或者组件层级较深时,性能可能会受到一定影响,尤其是在频繁更新数据的情况下。
  • 由于需要递归遍历嵌套对象,可能会导致性能瓶颈。

2.vue3

  • 通过静态提升、事件侦听器缓存等编译优化技术,提高了性能。静态提升可以避免在每次渲染时重复创建静态节点,事件侦听器缓存可以减少不必要的事件绑定和解绑操作。
  • Proxy的使用本身也在一定程度上提高了性能,尤其是对于复杂的数据结构。
4.开发体验

1.vue2:

  • 在处理响应式数据时,需要注意一些特殊情况和方法的使用,开发体验相对来说不够简洁。
  • 对于大型项目,响应式数据的管理可能会变得复杂。

2.vue3

  • 响应式系统更加直观和简洁,开发者可以更自然地操作数据,无需过多担心响应式的特殊处理。
  • 组合式 API 的引入,使得响应式数据的管理更加清晰和可维护,提高了开发体验。
  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值