亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Vue3中watch無法監(jiān)聽的解決辦法

 更新時間:2023年05月08日 10:46:19   作者:廣寶哥  
本文主要介紹了Vue3中watch無法監(jiān)聽的解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

下面的代碼在對ref實例賦值完之后。既:test.value = { name: 1 },會發(fā)現(xiàn)不執(zhí)行watch里面的回調函數(shù)了,這是為什么呢?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="../../dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
  </div>
  <script>  
    var { createApp, ref, watch, onMounted  } = Vue;
    var app = createApp({
        setup() {
            var test = ref({});
            onMounted(() => {
              test.value = { name: 1 }
            })
            setInterval(() => {
              test.value.name++
            }, 3000)
            watch(test.value, () => {
              debugger
            })
            return {
                test,
            }
        }
    })
    app.mount('#app')
  </script>
  <script>
  </script>
</body>
</html>

1:定義ref類型的響應式var test = ref({}), 然后開始執(zhí)行watch(test.value, cb)函數(shù)

2: 這時候觸發(fā)了test.value,也就是ref中的get value()方法,該方法會執(zhí)行trackRefValue(this)

export function trackRefValue(ref: RefBase<any>) {
  if (shouldTrack && activeEffect) {
    ref = toRaw(ref)
    if (__DEV__) {
      trackEffects(ref.dep || (ref.dep = createDep()), {
        target: ref,
        type: TrackOpTypes.GET,
        key: 'value'
      })
    } else {
      trackEffects(ref.dep || (ref.dep = createDep()))
    }
  }
}
  • 就是為當前ref實例,收集依賴,但是發(fā)現(xiàn)shouldTrack為false, activeEffect為undefined,所以不執(zhí)行后面的邏輯

3:觸發(fā)ref的get value() 方法之后,開始執(zhí)行watch函數(shù)了

3-1: test.value是響應式屬性,所以isReactive(source)為true, deep為true 如何包裹一層函數(shù)

if (cb && deep) {
  const baseGetter = getter
  getter = () => traverse(baseGetter())
}

4: 然后實例化構造函數(shù)const effect = new ReactiveEffect(getter, scheduler), 執(zhí)行effect.run()

執(zhí)行getter = () => traverse(baseGetter()) 為test.value里面的屬性搜集ReactiveEffect依賴

5: onMounted之后,直接替換test.value的值,觸發(fā)了set value()方法

5-1:對新設置的值,重新定義proxy響應式屬性toReactive(newVal)

并且觸發(fā)triggerRefValue(this, newVal), 觸發(fā)依賴的執(zhí)行

set value(newVal) {
    const useDirectValue =
      this.__v_isShallow || isShallow(newVal) || isReadonly(newVal)
    newVal = useDirectValue ? newVal : toRaw(newVal)
    if (hasChanged(newVal, this._rawValue)) {
      this._rawValue = newVal
      this._value = useDirectValue ? newVal : toReactive(newVal)
      triggerRefValue(this, newVal)
    }
}

但是get value()的時候,沒有收集到ReactiveEffect,所以執(zhí)行triggerRefValue(this, newVal) 的時候,沒有執(zhí)行到watch的回調函數(shù)

6:后面執(zhí)行setInterval對test.value進行賦值的時候,也沒有更新watch的回調,因為set value()的時候 重新執(zhí)行了一次toReactive(newVal) 之前收集的依賴已經(jīng)失效了

7:解決方法

// 方法一
watch(() => test.value, () => {
  debugger
}, { deep: true })
// 方法二
watch(test, () => {
  debugger
}, { deep: true })
// 方法三, 在test.value賦值之后執(zhí)行watch
var { createApp, ref, watch, onMounted  } = Vue;
    var app = createApp({
        setup() {
            var test = ref({});
            onMounted(() => {
              test.value = { name: 1 }
              watch(test.value, () => {
                debugger
              })
            })
            setInterval(() => {
              test.value.name++
            }, 3000)
            // watch(test.value, () => {
            //   debugger
            // })
            return {
                test,
            }
        }
    })
app.mount('#app')

這個寫法,不會一開始就觸發(fā)ref實例的get value()方法, 而是在創(chuàng)建 const effect = new ReactiveEffect(getter, scheduler) ,執(zhí)行effect.run() 的時候,觸發(fā)get value()方法,搜集依賴

7-1:當對test.value = {name: 1}賦值的時候,觸發(fā)set value()方法,就可以觸發(fā)triggerRefValue(this, newVal) 執(zhí)行依賴,從而可以再次對新的值,重新搜集依賴

總結

普通的寫法進行監(jiān)聽,對ref的值進行賦值,既:test.value = { name: 1 },在get vlaue()的時候,沒有收集 到watch的依賴,在觸發(fā)set value()的時候,就沒有再行watch了

而加了函數(shù)包裹test.value,在執(zhí)行effect.run()的時候,才會觸發(fā)ref的get value(), 從而可以執(zhí)行trackRefValue(this)收集到依賴

watch(() => test.value, () => {
  debugger
}, { deep: true })
export function trackRefValue(ref: RefBase<any>) {
  if (shouldTrack && activeEffect) {
    ref = toRaw(ref)
    if (__DEV__) {
      trackEffects(ref.dep || (ref.dep = createDep()), {
        target: ref,
        type: TrackOpTypes.GET,
        key: 'value'
      })
    } else {
      trackEffects(ref.dep || (ref.dep = createDep()))
    }
  }
}

再觸發(fā)set value()的時候,也就可以重新觸發(fā)effect.run()

到此這篇關于Vue3中watch無法監(jiān)聽的解決辦法的文章就介紹到這了,更多相關Vue3 watch無法監(jiān)聽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Vue組件實現(xiàn)觸底判斷

    Vue組件實現(xiàn)觸底判斷

    這篇文章主要為大家詳細介紹了Vue組件實現(xiàn)觸底判斷,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • vue學習筆記之vue1.0和vue2.0的區(qū)別介紹

    vue學習筆記之vue1.0和vue2.0的區(qū)別介紹

    今天我們來說一說vue1.0和vue2.0的主要變化有哪些?對vue相關知識感興趣的朋友一起學習吧
    2017-05-05
  • Vue3源碼分析組件掛載初始化props與slots

    Vue3源碼分析組件掛載初始化props與slots

    這篇文章主要為大家介紹了Vue3源碼分析組件掛載初始化props與slots實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • vue組件之間數(shù)據(jù)傳遞的方法實例分析

    vue組件之間數(shù)據(jù)傳遞的方法實例分析

    這篇文章主要介紹了vue組件之間數(shù)據(jù)傳遞的方法,結合實例形式分析了vue.js父組件與子組件之間數(shù)據(jù)傳遞相關操作技巧,需要的朋友可以參考下
    2019-02-02
  • 前端vue項目如何使用Decimal.js做加減乘除求余運算

    前端vue項目如何使用Decimal.js做加減乘除求余運算

    decimal.js是使用的二進制來計算的,可以更好地實現(xiàn)格化式數(shù)學運算,對數(shù)字進行高精度處理,使用decimal類型處理數(shù)據(jù)可以保證數(shù)據(jù)計算更為精確,這篇文章主要給大家介紹了關于前端vue項目如何使用Decimal.js做加減乘除求余運算的相關資料,需要的朋友可以參考下
    2024-05-05
  • 詳解Vue.js——60分鐘組件快速入門(上篇)

    詳解Vue.js——60分鐘組件快速入門(上篇)

    本篇文章主要介紹了Vue.js組件,組件系統(tǒng)是Vue.js其中一個重要的概念,具有一定的參考價值,有需要的可以了解一下。
    2016-12-12
  • vue使用Office?Web實現(xiàn)線上文件預覽

    vue使用Office?Web實現(xiàn)線上文件預覽

    這篇文章主要為大家介紹了vue使用微軟的開發(fā)接口Office?Web,實現(xiàn)線上文件預覽,預覽word,excel,pptx,pdf文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • vxe-table如何在單元格中渲染簡單的餅圖

    vxe-table如何在單元格中渲染簡單的餅圖

    這篇文章主要介紹了vxe-table如何在單元格中渲染簡單的餅圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue 添加vux的代碼講解

    vue 添加vux的代碼講解

    通過命令npm install vux --save添加vux,在相關配置文件中配置信息,具體代碼添加方法,大家參考下本文
    2017-11-11
  • Vue基于vuex、axios攔截器實現(xiàn)loading效果及axios的安裝配置

    Vue基于vuex、axios攔截器實現(xiàn)loading效果及axios的安裝配置

    這篇文章主要介紹了Vue基于vuex、axios攔截器實現(xiàn)loading效果及axios的安裝配置,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04

最新評論