ref本质也是reactive,ref(obj)等价于reactive({value: obj})
vue3中实现响应式数据的方法是就是使用ref和reactive,所谓响应式就是界面和数据同步,能实现实时更新
vue2中响应式是通过defineProperty实现的,vue3中是通过ES6的Proxy来实现的
reactive的参数必须是一个对象,包括json数据和数组都可以,否则不具有响应式
如果给reactive传递了其他对象(如时间对象),默认情况下修改对象界面不会自动更新,如果想更新,可以通过给对象重新赋值来解决。
{{ info.name }} -- {{ info.age }}
ref的参数可以是基本数据类型,也可以是引用数据类型。ref会把参数加工成一个响应式对象。如果使用的是基本类型响应式依赖Object.defineProperty( ),如果ref使用的是引用类型,底层ref会借助reactive的proxy 定义响应式。
{{ num }}
ref和reactive都属于递归监听,也就是数据的每一层都是响应式的,如果数据量比较大,非常消耗性能,非递归监听只会监听数据的第一层
ref和reactive定义的数据每一层都是响应式数据,使用shallowRef和shallowReactive后只有第一层数据具备响应式。语法和ref和reactive一致
{{ infos.name }}
{{ num }}
注意:shallowReactive没有类似triggerRef()的方法
{{ infos.name }} -- {{ infos.child.name }}
{{ num }}
有些时候我们不希望数据进行响应式实时更新,可以通过toRaw获取ref或reactive引用的原始数据,通过修改原始数据,不会造成界面的更新,只有通过修改ref和reactive包装后的数据时才会发生界面响应式变化。
{{ info.name }}
markRaw包装后的数据永远不会被追踪。暂时没发现有啥用,看个热闹即可
toRef 是对定义的响应对象的某个属性进行引用
{{ info.name }} --- {{ info.age }}
遍历对象中的所有属性,将其变为响应式数据,这是因为toRef只能传一个key,toRefs所达到的效果与toRef一样
以上最常用的是ref 和 reactive 其它 看个热闹即可
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:{
foo: Ref,
bar: Ref
}
*/
// 这个 ref 和源属性已经“链接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3