响应式reactive
reactive()
返回一个对象的响应式代理。
一般ref绑定的是基本数据类型,如果绑定的是复杂型类型,ref会自动条用toReactive方法,相当于就是使用reactive()
reactive绑定的是复杂型数据类型,会判断是为引用类型,如果不是会抛出警告
响应式时深层转换的,影响所有嵌套属性,如果对象中有ref属性,也将解析,同时保持响应性
值得注意的是,当访问到某个响应式数组或 Map 这样的原生集合类型中的 ref 元素时,不会执行 ref 的解包。
若要避免深层响应式转换,只想保留对这个对象顶层次访问的响应性,请使用 shallowReactive() 作替代。
返回的对象以及其中嵌套的对象都会通过 ES Proxy 包裹,因此不等于源对象,建议只使用响应式代理,避免使用原始对象。
import { reactive, readyonly, } from 'vue'
const person = reactive({
name: '张三',
age: 18
})
person.age++
// ref的解包
const count = ref(1)
const obj = reactive({ count })
// ref 会被解包,不需要在.value, ref更新或reactive更新都会同步
console.log(obj.count === count.value) // true
// 会更新 `obj.count`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2
// 也会更新 `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3
// 如果响应式数据为数组或map对象集合中的ref元素时,不会解包ref
const arr = reactive([ref(1)])
console.log(arr[0].value) // 不会解包,需手动.value
const map = reactive(new Map([['count', ref(0)]]))
console.log(map.get('count').value)
// 将一个 ref 赋值给为一个 reactive 属性时,该 ref 会被自动解包:
const count = ref(1)
const obj = reactive({})
obj.count = count
console.log(obj.count) // 1
console.log(obj.count === count.value) // true
readonly()
接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。其他都与reactive一样
const original = reactive({ count: 0 })
const copy = readonly(original)
watchEffect(() => {
// 用来做响应性追踪
console.log(copy.count)
})
// 更改源属性会触发其依赖的侦听器
original.count++
// 更改该只读副本将会失败,并会得到一个警告
copy.count++ // warning!
shallowReactive()
reactive() 的浅层作用形式。一个浅层响应式对象会有根级别的属性时响应式的,
const person = shallowReactive({
name: "张三",
age: 20,
other: {
hobby: 18,
},
});
const increament = () => {
person.other.hobby++; //dom挂在后, 不是响应式的,不会更新视图
// person.age++; // 更新顶层会导致hobby也会更新,ref会收集依赖更新
};
person.other.hobby++; // 在挂在dom之前更改值,最终视图显示的是最后更改的值
shallowReadonly()
readonly() 的浅层作用形式
const state = shallowReadonly({
foo: 1,
nested: {
bar: 2
}
})
// 更改状态自身的属性会失败
state.foo++
// ...但可以更改下层嵌套对象
isReadonly(state.nested) // false
// 这是可以通过的
state.nested.bar++

浙公网安备 33010602011771号