# shallowReactive 与 shallowRef
-
shallowReactive : 只处理了对象内最外层属性的响应式(也就是浅响应式)
-
shallowRef: 只处理了value的响应式, 不进行对象的reactive处理
-
什么时候用浅响应式呢?
- 一般情况下使用ref和reactive即可,都是深度响应式
- 如果有一个对象数据, 结构比较深, 但变化时只是外层属性变化 ===> shallowReactive
- 如果有一个对象数据, 后面会产生新的对象来替换 ===> shallowRef
-
shallowReactive 浅响应式:
点击按钮时,只更新num.a不可以更新,更新name可以更新;<template> <h2>shallowReactive</h2> <h3>m:{{m}}</h3> <hr> <button @click="update">点击更新数据</button> </template> <script lang="ts"> import { defineComponent, shallowReactive } from "vue"; export default defineComponent({ name: "App", setup() { // 浅响应式 const m = shallowReactive({ name: 'balance', age: 20, num: { a: "a", b: 2 } }) const update = () => { // m.name += "+++" m.num.a += "+++" console.log(m); } return { m, update }; }, }); </script>
-
shallowRef:name、num.a 都不更新
<template> <h2>shallowRef</h2> <h3>m:{{ m }}</h3> <hr /> <button @click="update">点击更新数据</button> </template> <script lang="ts"> import { defineComponent, shallowRef } from "vue"; export default defineComponent({ name: "App", setup() { const m = shallowRef({ name: "balance", age: 20, num: { a: "a", b: 2, }, }); const update = () => { m.value.num.a += "+++"; m.value.name += "+++" console.log(m); }; return { m, update, }; }, }); </script>
# readonly 与 shallowReadonly
- readonly:
- 深度只读数据
- 获取一个对象 (响应式或纯对象) 或 ref 并返回原始代理的只读代理。
- 只读代理是深层的:访问的任何嵌套 property 也是只读的。
- shallowReadonly
- 浅只读数据
- 创建一个代理,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换
- 应用场景:
-
在某些特定情况下, 我们可能不希望对数据进行更新的操作, 那就可以包装生成一个只读代理对象来读取数据, 而不能修改或删除
<template> <h3>readonly:{{state1}}</h3> <h3>shallowReadonly:{{state1}}</h3> <hr> <button @click="update">更新数据</button> </template> <script lang="ts"> import { defineComponent, reactive, readonly, shallowReadonly } from "vue"; export default defineComponent({ name: "App", setup() { const state = reactive({ name: 'balance', num: { a: "1", b: 2 } }) const state1 = readonly(state) const state2 = shallowReadonly(state) function update() { state2.name += "===" state2.num.a += "===" // 可以修改 state1.name += "===" state1.num.a += "===" } return { state, state1, update }; }, }); </script>
-
# toRaw 与 markRaw
toRaw可以将响应式数据还原成普通数据;markRaw进行标记,新增加的数据不再为响应式数据
- toRaw
- 返回由
reactive
或readonly
方法转换成响应式代理的普通对象。 - 这是一个还原方法,可用于临时读取,访问不会被代理/跟踪,写入时也不会触发界面更新。
- 返回由
- markRaw
- 标记一个对象,使其永远不会转换为代理。返回对象本身
- 应用场景:
- 有些值不应被设置为响应式的,例如复杂的第三方类实例或 Vue 组件对象。
- 当渲染具有不可变数据源的大列表时,跳过代理转换可以提高性能。
<template> <h2>{{ state }}</h2> <button @click="testToRaw">测试toRaw</button> <button @click="testMarkRaw">测试markRaw</button> </template> <script lang="ts"> import { markRaw, reactive, toRaw, } from 'vue' export default { setup() { const state = reactive<any>({ name: 'balance', age: 20, }) const testToRaw = () => { const user = toRaw(state) user.age++ // 界面不会更新 console.log(user); // 普通对象 console.log(state); // 响应式对象 } const testMarkRaw = () => { const likes = ['a', 'b'] // state.likes = likes state.likes = markRaw(likes) // likes数组就不再是响应式的了 setTimeout(() => { state.likes[0] += '--' }, 1000) console.log(state); } return { state, testToRaw, testMarkRaw, } } } </script>