本文主要介绍了vue3中ref、reactive的使用。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
在讲解这两个api工具之前,我们得先了解下watch和watchEffect这两个函数的使用方法和它的一些惊人的秘籍。
目录
watch和watchEffect的秘籍
watch
watchEffect
ref、reactive的理解
ref
reactive
扩展知识
toRef
toRefs
shallowRef
shallowReactive
总结
watch和watchEffect的秘籍
watch
其实,watch我们可以简单的理解为vue2中的watch勾子函数。就是监听数据发生变化时所执行的操作。它有三个参数,分别如下。
参数一:需要监听的数据(可以是任意的数据类型,整型、字符串、布尔值、json对象、数组)
参数二:数据发生变化时所执行的操作(回调函数有两个参数,发生变化后的新值,和旧值)
参数三:额外的配置项(它是一个可选的参数)
参数一和参数二我就不多说,应该都能理解。在这儿我讲解下参数三的使用规则。虽然参数三是一个可选项,但它的配置会引发整个wath函数的使用规则。参数三主要有以下几个配置
const info = reactive({a:5,b:6})
watch(info,(n,o)=>{console.log(n , 'n')},{deep:true, //是否深度监听 immediate:true, //是否在监听时立即触发,我们可以简单理解成页面加截完成时就执行flush:'post' ,//调整回调函数的刷新时机(这个我还没理解透)}
)
watchEffect
watchEffect 跟 watch 类似,但它也有些不太一样的地方。watchEffect它是立即执行的。也就是说,只要有监听,它就会立即监听,这不同于 watch。watch如果在配置中配置 immediate:false,那它就不会立即监听,只有被监听的数据发生变化时才会执行监听的动作。而在watchEffect中,它的参数有两个
参数一:副作用函数,也就是说,监听到数据时所需要执行操作。不管是哪个数据,只有有监听,它就会执行。
参数二:配置项(可选参数)
watchEffect(()=>{//执行的副作用函数
} , {flush:'post'
})
ref、reactive的理解
在简简理解 watch 和 watchEffect 之后,我们来理解下开发中最最常用的两个函数,ref 、reactive。虽然这两个函数都是响应式的函数,但它还是有一些区别的。
ref
ref一般用来定义基础的数据类型,整型,字符串、布尔值。虽然它也可以定义复杂的数据类型(数组、json对象)但不建议这样子去弄。按官方文档的来。
const num = ref(5); //定义
console.log(num.value) //注意:取值的时候需要使用 .value 才能取得到值
reactive
reactive它是用来定义复杂的数据类型。数组、json对象,它取值的时候只需要变量.key就可以了。
const info = reactive({name:'xiaobing' , age:15})
console.log(info.age)
console.log(info.name)
扩展知识
toRef
toRef的做用就是把 reactive 里面的每一个key抽出来,转换成一个基本的数据类型。而抽离出来的数据仍旧是一个响应式的数据。
const info = reactive({name:'xiaobing' , age:15})
const name = toRef(info , 'name')watch(info,(n,o)=>{console.log(n , 'n')},{deep:true, //是否深度监听 immediate:true, //是否在监听时立即触发,我们可以简单理解成页面加截完成时就执行flush:'post' ,//调整回调函数的刷新时机(这个我还没理解透)}
)//点击按纽的事件
const check = ()=>{name.value = 'hello xiaobing'
}
toRefs
相应的,toRefs跟 toRef 类似,只是他解出来的是一个数组。也是一个响应式的数据
const info = reactive({name:'xiaobing' , age:15})
const { name , age } = toRefs(info)watch(info,(n,o)=>{console.log(n , 'n')},{deep:true, //是否深度监听 immediate:true, //是否在监听时立即触发,我们可以简单理解成页面加截完成时就执行flush:'post' ,//调整回调函数的刷新时机(这个我还没理解透)}
)//点击按纽的事件
const check = ()=>{name.value = 'hello xiaobing'
}
shallowRef
对于 shallowRef 中定义的复杂数据类型,如果只是单纯.value.xxx ,它是不会执行响应式数据更新。只有把整个大的对象一起更新,才会执行响应试数据更新。下面的例子我用的是json对象,数组也是一样的道理。或者,我们换一句话来说,shallowRef 它是浅层式更新的。
const info = shallowRef({name:'xiaobing' , age:15})watch(info,(n,o)=>{console.log(n , 'n')},{deep:true, //是否深度监听 immediate:true, //是否在监听时立即触发,我们可以简单理解成页面加截完成时就执行flush:'post' ,//调整回调函数的刷新时机(这个我还没理解透)}
)//点击按纽的事件
const check = ()=>{info.value.name = 'hello xiaobing' //它并不会执行晌应式更新info.value = {name:'hello world' , age:15}; //这个时候它会执行响应式更新
}
shallowReactive
shallowReactive 它同样是浅层式更新。在上文我们说过 reactive 是用来定义复杂的数据类型。在这儿,我们可以这样来定义 。把 shallowReactive 也定义一个 json 对象的数据类型。但这个json 对象是多层次的。这时,就会发现,只有第一层的数据是响应式的。之后的数据并不会执行响应式的更新。
const userInfo = shallowReactive({id:5,info:{name:'xiaobing',age:15,}
})watch(userInfo,(n,o)=>{console.log(n , 'n')},{deep:true, //是否深度监听 immediate:true, //是否在监听时立即触发,我们可以简单理解成页面加截完成时就执行flush:'post' ,//调整回调函数的刷新时机(这个我还没理解透)}
)//点击按纽的事件
const check = ()=>{userInfo.id = 66; //执行响应式更新userInfo.info.name = 'hello xiaobing' //不执行响应式的更新
}
总结
从这几个小例子我们可以看出,官方为什么不建议对于复杂的数据类型用 ref 来定义。虽然定义程序也并不会报错。但如果随着功能和程序的迭代。维护也是一个很大的成本。