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响应式的区别的主要内容,如果未能解决你的问题,请参考以下文章