最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

下面的代碼在對(duì)ref實(shí)例賦值完之后。既:test.value = { name: 1 },會(huì)發(fā)現(xiàn)不執(zhí)行watch里面的回調(diào)函數(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類型的響應(yīng)式var test = ref({}), 然后開始執(zhí)行watch(test.value, cb)函數(shù)

2: 這時(shí)候觸發(fā)了test.value,也就是ref中的get value()方法,該方法會(huì)執(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()))
    }
  }
}
  • 就是為當(dāng)前ref實(shí)例,收集依賴,但是發(fā)現(xiàn)shouldTrack為false, activeEffect為undefined,所以不執(zhí)行后面的邏輯

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

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

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

4: 然后實(shí)例化構(gòu)造函數(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:對(duì)新設(shè)置的值,重新定義proxy響應(yīng)式屬性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()的時(shí)候,沒有收集到ReactiveEffect,所以執(zhí)行triggerRefValue(this, newVal) 的時(shí)候,沒有執(zhí)行到watch的回調(diào)函數(shù)

6:后面執(zhí)行setInterval對(duì)test.value進(jìn)行賦值的時(shí)候,也沒有更新watch的回調(diào),因?yàn)?code>set value()的時(shí)候 重新執(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')

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

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

總結(jié)

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

而加了函數(shù)包裹test.value,在執(zhí)行effect.run()的時(shí)候,才會(huì)觸發(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()的時(shí)候,也就可以重新觸發(fā)effect.run()

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

相關(guān)文章

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

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

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

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

    今天我們來(lái)說(shuō)一說(shuō)vue1.0和vue2.0的主要變化有哪些?對(duì)vue相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2017-05-05
  • Vue3源碼分析組件掛載初始化props與slots

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

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

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

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

    前端vue項(xiàng)目如何使用Decimal.js做加減乘除求余運(yùn)算

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

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

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

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

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

    vxe-table如何在單元格中渲染簡(jiǎn)單的餅圖

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

    vue 添加vux的代碼講解

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

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

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

最新評(píng)論

鄂托克前旗| 新巴尔虎右旗| 彭水| 尚志市| 天水市| 澄江县| 林周县| 宜昌市| 出国| 丰镇市| 陈巴尔虎旗| 安阳县| 丰城市| 常熟市| 黎川县| 山东| 十堰市| 都江堰市| 吴川市| 象山县| 商水县| 罗城| 高雄县| 嘉禾县| 大宁县| 界首市| 静宁县| 天台县| 新宁县| 黔西| 乐清市| 铜山县| 莒南县| 镇远县| 古丈县| 五莲县| 安阳市| 夏津县| 塔河县| 庆安县| 桓台县|