Vue响应式的原理

一. Vue响应式原理的核心概念

1. Vue响应式原理基于以下核心概念:

① 响应式对象:Vue使用Object.defineProperty()来  reactive(反应)对象中的属性,使其变化可以被检测。
注意:
        ★ Object.defineProperty() 是JavaScript中的一个方法,‌用于在一个对象上定义新属性或修改现有属性。‌这个方法接收三个参数:‌目标对象、‌属性名称和一个描述符对象。‌描述符对象可以包含以下属性:‌
     ☆ value:‌属性的值。‌可以是任何类型的值。‌
     ☆ writable:‌一个布尔值,‌表示属性值是否可以被改变。‌默认为false。‌
     ☆ enumerable:‌一个布尔值,‌表示属性是否可以在for...in循环或Object.keys()中被枚举。‌默认为false。‌
     ☆ configurable:‌一个布尔值,‌表示属性是否可以被删除或改变其属性描述符。‌默认为false。‌
        ★ reactive是vue.js中用于创建响应式数据的一个函数,其作用是将普通JavaScript对象转换成响应式对象,使其能自动更新视图。通过依赖关系追踪系统,当响应式数据的值发生变化时,所有依赖数据的视图组件都会自动更新,从而简化开发并优化性能。

② 依赖追踪:对每个响应式属性,维护一个依赖(Dependency)的列表,这些依赖是Watcher对象
注意
        ★ Watcher对象:是一个观察者对象,‌用于监听数据的变化执行相应的回调函数

③ 虚拟DOM:使用虚拟节点(VNode)进行高效的DOM更新
注意
        ★ 虚拟节点(‌Virtual Node,‌简称VNode)‌:是一种用JavaScript对象来描述DOM树结构的概念。‌它是Vue框架中的一个核心概念,‌用于高效地渲染和更新视图。‌虚拟节点本质上是一个普通的JS对象,‌用于描述视图的界面结构。‌

④ 事件侦听和触发:通过emit方法on方法来触发和监听事件,从而触发Watcher的重新计算和DOM的更新。
注意
        ★ emit方法是Vue实例中用来触发事件的方法,‌用于在子组件中触发一个自定义事件,‌并将数据作为参数传递给父组件,可以通过在组件中使用$emit方法来触发事件。‌
        ★ $on方法是一个用于监听自定义事件的方法允许在一个组件中监听自定义事件,‌并在事件触发时执行一个回调函数,可以实现组件之间的通信,‌尤其是当子组件需要向父组件发送信息时,能够构建更灵活和可维护的应用程序。

2. 以下是一个简化的响应式系统的例子:

注意:这个例子中,我们创建了一个简化版的Vue类,它具有响应式数据和$watch方法来观察这些数据的变化。当数据属性被设置时,它会通知依赖(Watcher)进行更新,并执行相应的回调函数。这个例子展示了Vue响应式系统的核心概念,但实际的Vue实现要复杂得多,包含更多优化和功能。 

二. Vue2和Vue3响应式原理的区别

1. Vue2的响应式原理:基于Object.defineProperty()实现的

★ Vue2通过Object.defineProperty()来实现数据的劫持,‌即对对象的属性进行拦截。‌通过getter(获取)函数setter(设置)函数来处理属性的读取和修改,‌当数据发生变化时,‌通过发布-订阅模式通知视图进行更新。‌此外,‌Vue2还通过重写数组的一系列方法来拦截数组的变更操作,‌如push、‌pop等,‌以确保数组的变更也能触发视图的更新。‌
注意
        ★ getter(获取)函数是一种用于从store中获取数据的函数,‌它类似于Vue组件中的计算属性,允许你从store中的state中提取数据,‌并且可以处理state中的数据,可以接受state作为第一个参数,‌也可以接受其他的getter函数作为第二个参数。Getter函数的结果会根据它的依赖进行缓存,‌只有当依赖发生变化时才会重新计算,这种机制在处理复杂状态逻辑时非常有用,‌因为它提供了对数据的计算和缓存机制,‌避免了不必要的重复计算。‌
        ★ setter(设置)函数是一种特殊的函数,‌用于设置对象的属性值通常与getter函数一起使用,‌它们共同构成了访问器属性(‌也称为存取器属性)‌,访问器属性包括getter和setter两部分,‌其中getter用于获取属性的值,‌而setter用于设置属性的值。‌在JavaScript中,‌可以通过Object.defineProperty()方法为对象定义getter和setter。‌当使用Object.defineProperty()为对象添加属性时,‌可以指定一个getter函数和一个(‌可选的)‌setter函数。‌当读取该属性时,‌getter函数会被调用;‌当修改该属性时,‌setter函数会被调用。‌
        ★ 具体来说,‌getter函数是一个不带参数的函数,‌它负责返回属性的值。‌而setter函数则负责设置属性的值,‌它接受一个参数,‌即要设置的新值。‌在setter函数的函数体中,‌任何的return语句都是无效的,‌因为setter函数的主要目的是修改属性的值,‌而不是返回一个新的值。‌

2. Vue3的响应式原理:基于ES6的Proxy实现的

★ Vue3引入了ES6的Proxy特性来实现数据的代理。‌通过Proxy对象来拦截对源对象的操作,‌包括属性的读取、‌设置、‌增加、‌删除等。‌当这些操作发生时,‌Vue3通过Reflect函数对源对象的属性进行操作,‌并通过定义Proxy对象的handler(操作者)来处理这些操作。‌这种方式不仅支持更多种类的数据结构,‌还提供了更灵活和强大的响应式功能。‌
注意
        ★ handler(操作者)通常指的是处理事件的函数,也就是与特定事件相关联的函数,在事件触发时被调用,‌以执行相应的操作或响应。‌在Vue实例中,‌可以通过在methods选项中定义handle函数,‌或者直接在Vue实例中定义一个匿名的handle函数来实现。‌handler函数可以接收事件对象作为参数,‌并根据需要传入其他参数。‌Vue允许在监听键盘事件时添加按键修饰符,‌以便在特定条件下调用handler函数。‌例如,可以使用@keyup.enter="submit"来监听键盘的回车键事件,‌当按下回车键时,‌调用submit函数。‌这种机制使得Vue能够灵活地处理各种用户交互事件,‌从而增强用户体验和应用程序的响应性

3. 区别

① 最主要的区别是 Vue 3 采用了 Proxproxy 来代替 Vue 2 中的 Object.defineProperty。
② Vue 3 使用 Proxy 替代了 Vue 2 中的 Object.defineProperty 主要有以下原因
        ★ Object.defineProperty 不能监听到属性的增加和删除,而 Proxy 可以。
        ★ Object.defineProperty 不能监听数组的索引和长度变化,而 Proxy 可以。
        ★ Proxy 可以直接监听整个对象不需要像 Vue 2 一样递归遍历每个属性
        ★ Proxy 返回的是一个新对象,我们可以只操作新对象达到间接修改原对象的目的,而 Vue 2 中,我们需要使用 Vue.set/vm.$set 这样的 API 来修改响应式对象,这种方式对用户不够友好。
③ 总的来说,Vue3的响应式系统相比Vue2更加现代化和灵活,‌能够更好地支持复杂的数据结构和操作。‌这种改进使得Vue3在处理大型应用和复杂状态管理时更加高效和便捷。

4. Vue 2 响应式系统示例:

 

5. Vue 3 响应式系统示例:

注意:在 Vue 3 中,我们使用 reactive (反应)函数来创建响应式对象,而在 Vue 2 中,我们使用 data(数据) 选项来创建响应式对象。另外,Vue 3 引入了 Composition API(组合式API,它允许我们更灵活地组合和重用代码。在 Vue 2 中,我们通常使用 mixins (混入)或者高阶组件来实现类似的功能,但是这些方法都有各自的问题和限制。
        ★ reactive(反应)函数是一个用于创建响应式对象的函数简单来说,‌reactive函数的作用是将一个普通的JavaScript对象转换成Vue的响应式对象,‌使得当该对象的属性发生变化时,‌Vue能够检测到这种变化并自动更新视图,这是Vue 3中实现数据驱动视图更新的重要机制之一。
        ★ data(数据)选项是一个特殊的配置项,‌用于存储组件中的数据在Vue.js中,‌data属性是组件的一个核心配置选项,‌它用于定义组件的状态。‌这个属性可以是一个对象,‌也可以是一个函数,‌具体取决于组件的使用场景。‌当data以对象的形式出现时,‌它通常用于根实例或非复用组件中,‌直接提供一个对象字面量来定义数据。‌这种方式下,‌data属性是一个普通的对象,‌直接作为组件实例的一个属性,‌通过对象属性初始化数据。‌这种方式的好处是语法简洁直观,‌方便管理多个属性,‌但缺点是所有组件实例可能共享同一个数据对象,‌导致数据污染的风险。
        ★ Composition API(组合式API是一种新的API集合,‌它允许开发者使用函数而不是声明选项的方式来书写Vue组件。‌这种API集合旨在提供一种更灵活、‌可重用的代码组织方式,‌以实现代码的共享和重用。‌Composition API是Vue 3.0引入的一个重要特性,‌它提供了一系列函数和工具,‌使得开发者能够更灵活地组织和共享代码逻辑,‌而无需依赖于传统的Vue实例。‌
        ★ mixins(混入)是一种分发Vue组件中可复用功能的非常灵活的方式,允许组件共享方法和属性,‌通过将公用的功能以对象的方式传入mixins选项中,‌当组件使用mixins对象时,‌所有mixins对象的选项都将被扩展到该组件本身的选项中。‌这意味着,‌如果多个组件需要共享某些功能,‌如数据、‌计算属性、‌方法等,‌可以通过定义一个mixins对象来实现,‌然后在需要的组件中使用这个mixins对象,‌从而避免代码重复和冗余,‌提高代码的重用性和可维护性。‌

 

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值