Vue3.0 ref、toRef、toRefs的區別
ref是對原始數據的拷貝,當修改ref數據時,模板中的視圖會發生改變,但是原始數據並不會改變。
toRef是對原始數據的引用,修改toRef數據時,原始數據也會發生改變,但是視圖並不會更新。
在vue3中定義一個基礎類型的響應式數據一般使用ref,定義一個引用類型的響應式數據一般使用reactive。
import {ref,reactive} from "vue" export default { setup(){ let num=ref(0) let obj=reactive({name:'張三',age:18}) return {num,obj} } }
這樣在模板中使用的時候,就可以直接通過{{num}},{{obj.name}},{{obj.age}}獲取數據了。
基礎類型的數據沒有問題,但是引用類型的值在模板中這樣寫就比較累贅了,我們也可以直接解構出來,在模板中就可以直接使用{{name}}和{{age}}了。
import {ref,reactive} from "vue" export default { setup(){ let num=ref(0) let obj=reactive({name:'張三',age:18}) let {name,age}=obj return {num,name,age} } }
toRef是將對象中的某個值轉化為響應式數據 toRef(obj,key)
import {toRef} from "vue" export default { setup() { let obj = { name: '張三', age: 18 }; let newObj = toRef(obj, 'name'); setTimeout(() => { newObj.value = '李四'; console.log(obj, newObj); //obj中的name和newObj都變成李四了,但是視圖顯示還是張三,不會變化 }, 2000); return { obj, newObj }; }, }; </script>
toRef是對原始數據的引用,修改toRef數據時,原始數據也會發生改變,但是視圖並不會更新。
toRefs是將整個對象轉化成響應式數據 toRefs(obj)
import {toRefs} from "vue" export default { let obj = { name: '張三', age: 18 }; let newObj = toRefs(obj); setTimeout(() => { newObj.name.value = '李四'; console.log(obj, newObj); }, 2000); return { obj, newObj }; }
需要注意的是,按照上面這種寫法,在模板中使用的時候,需要按照這種方式 {{newObj.name.value}}(不太理解),如果想直接使用{{name}},那么在setup中return的時候需要解構下
import {toRefs} from "vue" export default { let obj = { name: '張三', age: 18 }; let newObj = toRefs(obj); setTimeout(() => { newObj.name.value = '李四'; console.log(obj, newObj); }, 2000); return { obj, ...newObj }; }
這樣在模板中就可以直接通過{{name}}來獲取了
小結一下
1、ref是對元數據的拷貝,修改響應式數據時不會影響之前的數據,視圖會更新
2、toRef和toRefs是對元數據的引用,修改響應式數據時,原數據也會改變,但是視圖不會更新,toRef修改的是對象的某個屬性,toRefs修改的是整個對象
3、toRefs的使用場景:如果想讓響應式數據和原來的數據關聯起來同步更新,並且不更新視圖,那么就可以使用toRefs
Vue3 Composition API: 對比ref和reactive https://zhuanlan.zhihu.com/p/267967246
全面解析Vue3 Reactive家族和Ref家族API https://www.jianshu.com/p/cfe25e757d0e
那么為什么Vue2的defineproperty並沒有區分基本數據類型和引用數據類型呢?
因為defineproperty就是Object的靜態方法,它只是為對象服務的,甚至無法對數組服務,因此Vue 2弄了一個data根對象來存放基本數據類型,這樣無論什么類型,都是根對象的property,所以也就能代理基本數據類型。而Proxy能對所有引用類型代理,Vue 3也不再用data根對象,而是一個個的變量,所以帶來了新問題,如何代理基本數據類型呢?並沒有原生辦法,只能構建一個{value: Proxy Object}結構的對象,這樣Proxy也就能代理了。