Vue3中,reactive()返回的是一个原始对象的代理,与原始对象是不相等的。
只有代理对象是响应式的,更改原始对象不会触发更新。
reactive():
1、仅对对象类型有效(对象、数组、Map、Set)
2、必须始终保持对该响应式对象的相同引用,不要随意替换
ref()方法:
1、用来创建可以使用任何值类型的响应式ref,可以解决上述的问题,可以响应式替换整个对象,解构时也不会丢失响应性
2、在模板中作为顶层属性被访问时,才会被自动“解包”
3、被嵌套在一个响应式对象中,作为属性被访问时,也会自动解包
<script setup>
1、要在组件模板中使用响应式状态,需要在setup()函数中定义并返回,这种手动暴露大量状态和方法太繁琐
2、可以将代码写在<script setup>中,<script setup>中的顶层导入和变量声明可在同一组件的模板中直接使用
不像选项式API需要依赖this上下文对象访问属性,被编译的模板可以直接访问<script setup>中定义的变量,无需从一个代码示例从中代理。
响应式:当数据改变后,Vue会通知到使用该数据的代码,也会触发视图的更新。
| 实现原理 | 实现方式 | ||
|---|---|---|---|
| Vue2 | Object.defineProperty | 1、通过observe函数遍历data每个属性;2、调用Object.defineProperty()对每个属性做响应式处理:利用拦截器属性get()和set()方法做订阅-发布处理。get:将当前的Watch对象存入subs; set:触发notify通知所有的Watch对象,进行更新视图 | 1、要遍历需要监听的每个对象的每个属性,对其添加definePropert方法;2、对象直接新添加的属性或删除已有属性,直接通过下标替换元素或更新length,界面不会自动更新,要通过Vue.set()、Vue.delete;3、数据的响应式处理和视图未完全解耦 |
| 实现原理 | 实现方式 | ||
|---|---|---|---|
| Vue3 | Proxy 代理:Proxy(target,handler) 第一个参数:目标对象;第二个参数:处理器对象,用来监视数据、数据操作get、set、delete | 1、拦截对data任意属性的任意操作,包括属性值的读写,属性的添加,属性的删除;2、通过reflect反射,动态对被代理对象的相应属性进行特定的操作 | 1、直接监听整个对象而非属性。动态为data添加属性时,不需要做任何处理,这个属性就已经是响应式的了。(不用循环遍历data的每个属性,对属性都做一遍响应式处理,而是直接代理整个data对象) |