Vue3.0中Ref與Reactive的區別示例詳析

Ref與Reactive

Ref

Ref 用來創建基礎類型的響應式數據,模板默認調用value顯示數據。方法中修改需要修改value的值才能修改

<!-- 模板語法> 
<template>
   <div>{{state}}</div>
</template> 
//js 腳本
setup(){
     let state = ref(10) 
     state.value = 11
     return {state}
}

Reactive

Reactive 用來創建引用類型的響應式數據,

<!-- 模板語法> 
<template>
   <div>{{state.name}}</div>
</template> 
//js 腳本
setup(){
     let state = reactive({name:'aaa'}}) 
     state.name = 'zhangsan'
     return {state}
}

Ref與Reactive的區別

Ref的本質是通過Reactive創建的,Ref(10)=>Reactive({value:10});

Ref在模板調用可以直接省略value,在方法中改變變量的值需要修改value的值,才能修改成功。Reactive在模板必須寫全不然顯示整個數據。

Reactive的本質是將每一層的數都解析成proxy對象,Reactive 的響應式默認都是遞歸的,改變某一層的值都會遞歸的調用一遍,重新渲染dom。

shallowRef 與shallowReactive

Ref與Reactive創建的都是遞歸響應的,將每一層的json 數據解析成一個proxy對象,shallowRef 與shallowReactive創建的是非遞歸的響應對象,shallowReactive創建的數據第一層數據改變會重新渲染dom

 var state = shallowReactive({
    a:'a',
    gf:{
       b:'b',
       f:{
          c:'c',
          s:{d:'d'}
       }
    }
 })
 state.a = '1'
 //改變第一層的數據會導致頁面重新渲染
 //state => Proxy {a:"a",gf:{...}}
//如果不改變第一層 隻改變其他的數據 頁面不會重新渲染 例如 state.gf.b = 2

通過shallowRef創建的響應式對象,需要修改整個value才能重新渲染dom

var state = shallowRef({
   a:'a',
    gf:{
       b:'b',
       f:{
          c:'c',
          s:{d:'d'}
       }
    }
})
state.value.a = 1
/*
並不能重新渲染,shallowRef的原理也是通過shallowReactive({value:{}})創建的,要修改value才能重新渲染
*/
state.value = {
    a:'1',
    gf:{
       b:'2',
       f:{
          c:'3',
          s:{d:'d'}
       }
    }
}

如果使用瞭shallowRef想要隻更新某一層的數據可以使用triggerRef

var state = shallowRef({
   a:'a',
    gf:{
       b:'b',
       f:{
          c:'c',
          s:{d:'d'}
       }
    }
})
state.value.gf.f.s.d = 4
triggerRef(state)

頁面就會重新渲染

toRaw —隻修改數據不渲染頁面

如果隻想修改響應式的數據不想引起頁面渲染可以使用toRaw這個方法

var obj = {name:'test'}
var state = reactive(obj)
var obj2 = toRaw(state)
obj2.name = 'zs'//並不會引起頁面的渲染

----
//如果是用ref 創建的 就要獲取value值
var obj = {name:'test'}
var state = ref(obj)
var obj2 = toRaw(state.value)

markRaw — 不追蹤數據

如果不想要數據被追蹤,變成響應式數據可以調用這個方法,就無法 追蹤修改數據重新渲染頁面

var obj = {name:'test'}
obj = markRaw(obj)
var state = reactive(obj)
state.name = 'zs'//無法修改數據 頁面也不會修改

toRef — 跟數據源關聯 不修改UI

如果使用ref 創建的響應式變量,不會與源數據關聯,如果想要與源數據關聯但數據更改不更新UI,就要使用toRef創建

var obj = {name:'test'}
var state = ref(obj.name)
state.name = 'zs' //此時obj的name 屬性值並不會改變,UI會自動更新

///
var obj = {name:'test'}
var state = toRef(obj,'name') //隻能設置一個屬性值
state.name = 'zs'//此時obj裡面的name屬性值會發生改變,但是UI 不會更新

toRefs —設置多個toRef屬性值

如果想要設置多個toRef屬性值,可以使用toRefs

var obj = {name:'test',age:16}
var state = toRefs(obj)
state.name.value = 'zs'//obj的name的屬性值也會改變,但UI不會更新
state.age.value = 18//obj的age的屬性值也會改變,但UI不會更新

customRef —自定義一個ref

通過customRef這個方法可以自定義一個響應式的ref方法

function myRef(value){
   /*
    customRef函數返回一個對象,對象裡面有2個方法,get/set方法,創建的對象獲取數據的時候能 訪問到get方法,創建的對象修改值的時候會觸發set 方法
    customRef函數有2個參數,track/trigger,track參數是追蹤的意思,get 的方法裡面調用,可以隨時追蹤數據改變。trigger參數 是觸發響應的意思,set 方法裡面調用可以更新UI界面
   */
    return customRef((track,trigger)=>{
       return {
          get(){
             track()//追蹤數據
             return value     
          },
          set(newVal){
             value = newVal
             trigger()//更新UI界面
          }
       }
    })

}

setup(){
   var age = myRef(18)
   age.value = 20
}

ref 捆綁頁面的標簽

vue2.0 可以通過this.refs拿到dom元素,vue3取消瞭這一操作,沒有瞭refs拿到dom 元素,vue3取消瞭這一操作,沒有瞭refs拿到dom元素,vue3取消瞭這一操作,沒有瞭refs這個屬性值,可以直接用ref()方法生成響應式變量與dom 元素捆綁

<template>
   <div ref="box"></div>

</template>
import {ref,onMounted} from 'vue'
/*
 setup 方法調用是在生命周期beforeCreate與created 之間
*/
<script>
   setup(){
      var box = ref(null)
      onMounted(()=>{
         console.log('onMounted',box.value)
      })
      console.log(box.value)
      return {box}

   }

</script>

總結

到此這篇關於Vue3.0中Ref與Reactive區別的文章就介紹到這瞭,更多相關Vue3.0 Ref與Reactive區別內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: