Vue3的ref和reactive區別及使用


  Vue3官方文檔中定義響應式數據使用ref()或者reactive()

 一、ref的研究

  1)ref創建一個響應式數據,一般來說用於創建簡單類型的響應式對象,比如StringNumber、boolean類型;

  2)當我們給ref傳遞一個值之后,如果使用的是基本類型響應式依賴Object.defineProperty( )的get( )和set( ),如果ref使用的是引用類型,ref函數底層會自動將ref轉換成reactive; ref(18) => reactive({value:18});

  3)需要注意的是ref定義的值在Vue中使用直接使用所定義的字段,但是在js中獲取或者修改值需要通過value;

  4)ref也可以創建引用類型,對於復雜的對象,值是一個被proxy攔截處理過的對象,但是里面的屬性不是RefImpl類型的對象,proxy代理的對象同樣被掛載到value上,所以可以通過obj.value.key來讀取屬性,這些屬性同樣也是響應式的,更改時可以觸發視圖的更新

  具體使用及結構打印如下:

 1 <template>
 2   <h3>{{ refBaseType }}</h3>
 3   <h3>{{ refReferenceType }}</h3>
 4 </template>
 5 
 6 <script setup>
 7 import { ref } from 'vue'
 8 let refBaseType = ref(null)
 9 //ref 需要用.value去獲取值
10 refBaseType.value = 'i am ref'
11 console.log('refBaseType', refBaseType)
12 //打印結果
13 /*
14 RefImpl {_shallow: false, dep: undefined, __v_isRef: true, _rawValue: "i am ref", _value: "i am ref"}
15 dep: undefined
16 __v_isRef: true
17 _rawValue: "i am ref"
18 _shallow: false
19 _value: "i am ref"
20 value: "i am ref"
21 __proto__: Object
22 * */
23 //如果ref使用的是對象,底層ref會借助reactive的proxy ******
24 let refReferenceType = ref({})
25 refReferenceType.value = { count: 1 }
26 console.log('refReferenceType', refReferenceType)
27 //打印結果
28 /*
29 RefImpl {_shallow: false, dep: undefined, __v_isRef: true, _rawValue: {…}, _value: Proxy}
30 dep: Set(1) {ReactiveEffect}
31 __v_isRef: true
32 _rawValue: {count: 1}
33 _shallow: false
34 _value: Proxy {count: 1}
35 value: Proxy  //如果ref使用的是對象,底層ref會借助reactive的proxy
36 [[Handler]]: Object
37 [[Target]]: Object
38 [[IsRevoked]]: false
39 
40 * */
41 </script>

 

  二、reactive研究

  1)reactive里面參數定義必須是對象或者數組(json/arr),本質將傳入的數據包裝成proxy對象;

  2)基於Es6的Proxy實現,通過Reflect反射代理操作源對象,相比於reactive定義的淺層次響應式數據對象,reactive定義的是更深層次的響應式數據對象;

  3)

 1 <template>
 2   <h3>{{ reactiveBaseType }}</h3>
 3   <h3>{{ reactiveReferenceType }}</h3>
 4   <div @click="setData">setData</div>
 5   <div @click="setReactive">setReactive</div>
 6 </template>
 7 
 8 <script setup>
 9 import { reactive } from 'vue'
10 let reactiveBaseType = reactive(null)
11 //reactive 無法定義基本類型的proxy,且設置值無法響應數據
12 let setData = () => {
13   reactiveBaseType = 'fai'
14 }
15 console.log('reactiveBaseType', reactiveBaseType)
16 //打印結果
17 /*
18 null
19 * */
20 //如果reactive使用的是引用類型
21 let reactiveReferenceType = reactive({ count: 1 })
22 let setReactive = () => {
23   //這樣設置會去proxy
24   reactiveReferenceType = { count: 1 }
25   console.log(reactiveReferenceType)
26   //打印結果
27   /*
28    *{count: 1} //proxy 沒了,所以reactive申明的無法直接替換整個對象,如果有這個需求請使用ref
29    * */
30 }
31 console.log('reactiveReferenceType', reactiveReferenceType)
32 //打印結果
33 /*
34 //proxy響應式
35 Proxy {count: 1}
36 [[Handler]]: Object
37 [[Target]]: Object
38 count: 1
39 __proto__: Object
40 [[IsRevoked]]: false
41 * */
42 </script>
43 
44 <style lang="scss" scoped>
45 
46 </style>

 

  三、總結

  1)一般來說,ref被用來定義簡單的字符串或者數值,而reactive被用來定義對象數組等

  2)實際上都能用,而且ref也可以去定義簡單的對象和數組,也是具有響應式的,不過官方文檔中有提到如果將對象分配為ref值,則可以通過reactive方法使該對象具有高度的響應式。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM