reactive 相关的函数
Vue3为 reactive 提供了一些列的函数,目的是可以更好的使用reactive,我们来一一了解一下。
readonly
返回对象(reactive、ref或者js对象)的只读代理。
简单的说就是返回一个只读副本,如果强行修改会出警告,并且不会修改成功。
定义两个readonly对象
const person = Vue.reactive({
name: 'jyk',
age: 100,
contact: {
QQ: 122345,
photo: 13012312314
}
})
// reactive 的 readonly
const myReatReadonly = Vue.readonly(person)
myReatReadonly.name = 'myReadonly' // 会出警告
console.log('myReatReadonly:', myReatReadonly)
// js对象的 readonly
const myObjectReadonly = readonly({
name:'object',
age: 100
})
console.log('myObjectReadonly:', myObjectReadonly)
打印出来看看到底是什么样子的。
-
reactive 的 Proxy
004reactive的Proxy
注意看,这个 Proxy 的 handler 有 has 和 ownKeys 两个函数,另外 set 有四个参数,可以和下面的 readonly的做对比。
-
readonly 的 Proxy
005readonly的Proxy
里面是reactive的代理,外面才是 readonly 的代理,set函数只有两个参数,要注意区分。
如果强行修改,会给出这样的警告
修改readonly的警告.png
-
js 对象的 readonly 的 Proxy
007object的readonly.png
handler 是一样的,Target 是 object 对象。
- 使用场景
vuex4.0 的 state 会自动变成reactive的形式,如果state有成员是对象的话,获取后也是reactive的形式,如果修改的话,就会直接修改 state,这样就不符合状态管理的风格要求。
那么就可以用readonly来返回state的只读副本,这样就可以避免直接修改state的情况了。
其他适合的场景。
简单类型不能使用 readonly
isProxy
检查对象是 reactive 还是 readonly创建的代理。
这是官网的介绍,我们来跑个代码看看
console.log('reactive:',isProxy(person))
console.log('readonly:',isProxy(myReatReadonly))
console.log('ObjectReadonly:',isProxy(myObjectReadonly))
console.log('isProxy:',isProxy({name:'isProxy'}))
打印出来看看:
008isProxy
好像有哪里不对,怎么都是 true?只有最后一个 js 对象才返回 false。
isReactive
检查对象是否是 reactive创建的响应式 proxy。
还是老规矩,挨个试验一下。
// isReactive
console.log('reactive:',isReactive(person))
console.log('readonly:',isReactive(myReatReadonly))
console.log('ObjectReadonly:',isReactive(myObjectReadonly))
console.log('isProxy:',isReactive({name:'isReactive'}))
打印看看
009isReactive
reactive 肯定是 true,js 对象也肯定是false,
那么readonly呢?那就要看看原对象是谁了?
- 如果原对象是reactive,也会返回 true
- 如果原对象是 js 对象,那么会返回 false
isReadonly
检查对象是否是由readonly创建的只读代理。
// isReadonly
console.log('reactive:',isReadonly(person))
console.log('readonly:',isReadonly(myReatReadonly))
console.log('ObjectReadonly:',isReadonly(myObjectReadonly))
console.log('isReadonly:',isReadonly({name:'isReadonly'}))
打印看看
010isReadonly
两个readonly返回 true,另外两个返回 false
如果想要得到非只读的 reactive,那么就要用 isReactive (true) 和 isReadonly(false) 一起来判断。
toRaw
简单的说,就是得到原始的js对象。
// toRaw
console.log('reactive:',Vue.toRaw(person))
console.log('readonly:',Vue.toRaw(myReatReadonly))
console.log('ObjectReadonly:',Vue.toRaw(myObjectReadonly))
console.log('toRaw:',Vue.toRaw({name:'toRaw'}))
看看效果就清楚了。
011toRaw.png
- 使用场景——前端存储
如果想把reactive存入前端存储的话,直接存入会报错,那么这时候就可以用toRaw来获取原始对象,存入前端存储了。
markRaw
简单的说,就是做个标记,不让标记的对象变成reactive的形式。
shallowReactive
浅层属性变成reactive的形式,深层的不变。
shallowReadonly
浅层属性变成只读的,深层的不变。
网友评论