其他分享
首页 > 其他分享> > [深入vue3之响应性API] reactive、readonly、shallowReactive、shallowReadonly、toRaw、markRaw等使用与讲解

[深入vue3之响应性API] reactive、readonly、shallowReactive、shallowReadonly、toRaw、markRaw等使用与讲解

作者:互联网

reactive

<script lang='ts' setup>
import { ref,reactive } from 'vue';
let rea1 = reactive({ count: 0 }) // Proxy

let refData = ref('1') // RedfImpl 构造函数的对象

//! ***reactive 将解包所有深层的 refs,同时维持 ref 的响应性。***  
//! ***正确的讲应该是:当它通过代理访问时,会被自动解包:***  
let rea2 = reactive<any>({refData})

//! 当将 ref 分配给 reactive property 时,效果同上
rea2.re2_1 = refData // console.log(rea2.re2_1)  > 打印 '1'

// 因为访问 reactive 内的 ref 会自动解包,所以不需要 .value
rea2.refData = '测试'

// 任何类型的新属性都是 proxy 类型
rea2.newObj = {data1:'同样是响应式的'}
</script>

readonly

<script lang='ts' setup>
import { ref,readonly } from 'vue';
let refData = ref('1') // RedfImpl 构造函数的对象

const read1 = readonly({a:1})
console.log(read1); // read1.count = 123 会报错

const read2 = readonly({refData}) // console.log(read2.refData); // 1
</script>

shallowReactive

<script lang='ts' setup>
import { shallowReactive } from 'vue';
const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2
  }
})

// 改变 state 本身的性质是响应式的
state.foo++
// ...但是不转换嵌套对象
isReactive(state.nested) // false
state.nested.bar++ // 非响应式
</script>

与 reactive 不同,任何使用 ref 的 property 都不会被代理自动解包。因为ref生成的是个对象!
例如 a = shallowReactive({ b:ref('1') }) 为 a.b.value,本质是嵌套的。


shallowReadonly

const state = shallowReadonly({
  foo: 1,
  nested: {
    bar: 2
  }
})

// 改变 state 本身的 property 将失败
state.foo++
// ...但适用于嵌套对象
isReadonly(state.nested) // false
state.nested.bar++ // 适用

与 readonly 不同,任何使用 ref 的 property 都不会被代理自动解包。因为ref生成的是个对象!

例如 a = shallowReadonly({ b:ref('1') }) 为 a.b.value,本质是嵌套的。


toRaw

<script lang='ts' setup>
import { toRaw } from 'vue';
const foo = {a:111}
const reactiveFoo = reactive(foo)
console.log(toRaw(reactiveFoo) === foo,reactiveFoo===foo) // true , 代理的则为false
</script>

markRaw

<script lang='ts' setup>
import { markRaw } from 'vue';
// markRaw 标记一个对象,使其永远不会转换为 proxy。返回对象本身。嵌套多深都不会转 proxy
// const foo = markRaw({}) 
// console.log(isReactive(reactive(foo))) // false
// // const bar = reactive({ foo }) // console.log(isReactive(bar.foo)) // false

const foo = markRaw({
  nested: {}
})
// markRaw 只作用于根级别,因此内部的子级对象会被转为响应式
// bar.nested是响应式的
const bar = reactive({
  // 虽然 `foo` 被标记为原始,但 foo.nested 不是。
  nested: foo.nested
})

let asx:any = reactive({a:123})
let as1 = markRaw({}) // 普通对象
let as2 = markRaw(asx) // 原始 asx; as2 === asx > true

</script>

其他更多vue3 选项式api、组合式api、全局/应用api学习经验分享

vue3 学习资料vue3学习资料记录,经验交流、分享https://oumae-kumiko.github.io/vue3.cn.community/

标签:shallowReadonly,对象,shallowReactive,nested,reactive,markRaw,foo,ref
来源: https://blog.csdn.net/lijiahui_/article/details/122539570