Vue3和Vue2响应式的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3和Vue2响应式的区别相关的知识,希望对你有一定的参考价值。

参考技术A 理解:Vue3.0中一个新的配置项,值为一个函数。

setup是所有 Composition API(组合API) “ 表演的舞台 ” 。

组件中所用到的:数据、方法等等,均要配置在setup中。

setup函数的两种返回值:

若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)

若返回一个渲染函数:则可以自定义渲染内容。(了解)

注意点:

尽量不要与Vue2.x配置混用

Vue2.x配置(data、methos、computed...)中 可以访问到 setup中的属性、方法。

但在setup中 不能访问到 Vue2.x配置(data、methos、computed...)。

如果有重名, setup优先。

setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

作用: 定义一个响应式的数据

语法: const xxx = ref(initValue)

创建一个包含响应式数据的 引用对象(reference对象,简称ref对象) 。

JS中操作数据: xxx.value

模板中读取数据: 不需要.value,直接:<div>xxx</div>

备注:

接收的数据可以是:基本类型、也可以是对象类型。

基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的。

对象类型的数据:内部 “ 求助 ” 了Vue3.0中的一个新函数—— reactive函数。

作用: 定义一个 对象类型 的响应式数据(基本类型不要用它,要用ref函数)

语法:const 代理对象= reactive(源对象)接收一个对象(或数组),返回一个 代理对象(Proxy的实例对象,简称proxy对象)

reactive定义的响应式数据是“深层次的”。

内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据进行操作。

vue2.x的响应式

实现原理:

对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。

数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

Object.defineProperty(data,'count',

get() ,

set()

)

存在问题:

新增属性、删除属性, 界面不会更新。

直接通过下标修改数组, 界面不会自动更新。

Vue3.0的响应式

实现原理:

通过Proxy(代理):  拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。

通过Reflect(反射):  对源对象的属性进行操作。

MDN文档中描述的Proxy与Reflect:

Proxy: https://developer.mozilla.org/zh-CN/docs/Web/javascript/Reference/Global_Objects/Proxy

Reflect: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect

newProxy(data,

    // 拦截读取属性值

get(target,prop)

    returnReflect.get(target,prop)

   ,

// 拦截设置属性值或添加新属性

set(target,prop,value)

    returnReflect.set(target,prop,value)

   ,

// 拦截删除属性

deleteProperty(target,prop)

    returnReflect.deleteProperty(target,prop)

  

)

proxy.name='tom'

从定义数据角度对比:

ref用来定义: 基本类型数据 。

reactive用来定义: 对象(或数组)类型数据 。

备注:ref也可以用来定义 对象(或数组)类型数据 , 它内部会自动通过reactive转为 代理对象 。

从原理角度对比:

ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。

reactive通过使用 Proxy 来实现响应式(数据劫持), 并通过 Reflect 操作 源对象 内部的数据。

从使用角度对比:

ref定义的数据:操作数据 需要 .value,读取数据时模板中直接读取 不需要 .value。

reactive定义的数据:操作数据与读取数据: 均不需要 .value。

setup执行的时机

在beforeCreate之前执行一次,this是undefined。

setup的参数

props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。

context:上下文对象

attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。

slots: 收到的插槽内容, 相当于 this.$slots。

emit: 分发自定义事件的函数, 相当于 this.$emit。

refreactivetoReftoRefs的作用与区别(Vue3学习记录)

Vue3中ref、reactive、toRef、toRefs都是与响应式数据相关的,就此做一份笔记作为区别

1.reactive[Obj]

reactive 用于为对象添加响应式状态。接收一个js对象作为参数,返回一个具有响应式状态的副本

  • 获取数据值的时候直接获取,不需要加.value
  • 参数只能传入对象类型
 const data=reactive({//可以创建响应式的对象
      counter:1,
      doubleCounter:computed(()=>{
       return  data.counter*2;
      })
    })

2.ref[data]

ref 用于为数据添加响应式状态

   //单值响应
      const msg2=ref(\'some msg\')

      //使用元素的引用
      const desc=ref(null);

  

3.toRef[data]

toRef 用于为源响应式对象上的属性新建一个ref,从而保持对其源对象属性的响应式连接。

接收两个参数:源响应式对象和属性名,返回一个ref数据。例如使用父组件传递的props数据时,要引用props的某个属性且要保持响应式连接时就很有用。

 const myTitle = toRef(props, \'title\')

    console.log(myTitle.value)

 

ref和toRef区别:
  • ref->复制出来一个新数据, 修改响应式数据不会影响原始数据
  • toRef->引用, 修改响应式数据会影响原始数据
  • ref->数据发生改变, 界面就会自动更新
  • toRef->数据发生改变, 界面也不会自动更新
 toRef应用场景:
      如果想让响应式数据和以前的数据关联起来, 并且更新响应式数据之后还不想更新UI, 那么就可以使用toRef

4.toRefs[arg1,...data]

可以理解为可以 解构赋值 的toRef
  • 获取数据值的时候需要加.value
  • toRefs后的ref数据不是原始数据的拷贝,而是引用,改变结果数据的值也会同时改变原始数据
  • 作用其实和 toRef 类似,只不过 toRef 是一个个手动赋值,而 toRefs 是自动赋值。
function userCounter() {  // counter相关
    const data=reactive({//可以创建响应式的对象
      counter:1,
      doubleCounter:computed(()=>{
       return  data.counter*2;
      })
    })

   
    return toRefs(data);//可以解构赋值
    }

解构赋值引用

 const {counter,doubleCounter}=userCounter();

 

学习引用:
https://blog.csdn.net/u010059669/article/details/112287552

以上是关于Vue3和Vue2响应式的区别的主要内容,如果未能解决你的问题,请参考以下文章

vue2.0和3.0的响应式原理以及区别

[vue3新特性] 12.组合api——13.toRef和toRefs

vue2数据响应式原理

Vue2 和 Vue3 中的 watch 用法

Vue2/Vue3 响应式原理

Vue3 响应式解析Reactivity(Reflect and Proxy)