欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

下面的代碼在對ref實(shí)例賦值完之后。既:test.value = { name: 1 },會發(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()方法,該方法會執(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:對新設(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對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è)寫法,不會一開始就觸發(fā)ref實(shí)例的get value()方法, 而是在創(chuàng)建 const effect = new ReactiveEffect(getter, scheduler) ,執(zhí)行effect.run() 的時(shí)候,觸發(fā)get value()方法,搜集依賴

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

總結(jié)

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

而加了函數(shù)包裹test.value,在執(zhí)行effect.run()的時(shí)候,才會觸發(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無法監(jiān)聽的解決辦法的文章就介紹到這了,更多相關(guān)Vue3 watch無法監(jiān)聽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue如何修改data中的obj數(shù)據(jù)的屬性

    vue如何修改data中的obj數(shù)據(jù)的屬性

    這篇文章主要介紹了vue如何修改data中的obj數(shù)據(jù)的屬性,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vue Router動態(tài)路由使用方法總結(jié)

    Vue Router動態(tài)路由使用方法總結(jié)

    這篇文章主要介紹了Vue Router動態(tài)路由使用方法總結(jié),需要的朋友可以參考下
    2023-10-10
  • Vue.js 中的異步組件是什么及使用異步組件的示例

    Vue.js 中的異步組件是什么及使用異步組件的示例

    異步組件是 Vue.js 中提高應(yīng)用程序性能和加載速度的重要功能之一,在使用異步組件時(shí),需要注意組件的加載時(shí)間、錯(cuò)誤處理和命名規(guī)范等問題,本文將介紹 Vue.js 中異步組件的概念、優(yōu)勢以及如何使用異步組件,感興趣的朋友一起看看吧
    2023-10-10
  • vue3常用的API使用簡介

    vue3常用的API使用簡介

    這篇文章主要介紹了vue3常用的API使用簡介,幫助大家更好的理解和學(xué)習(xí)使用vue,感興趣的朋友可以了解下
    2021-03-03
  • vue.js提交按鈕時(shí)進(jìn)行簡單的if判斷表達(dá)式詳解

    vue.js提交按鈕時(shí)進(jìn)行簡單的if判斷表達(dá)式詳解

    這篇文章主要給大家介紹了關(guān)于vue.js提交按鈕時(shí)如何進(jìn)行簡單的if判斷表達(dá)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • 詳解vue組件之間相互傳值的方式

    詳解vue組件之間相互傳值的方式

    這篇文章主要介紹了vue組件之間相互傳值的方式,對vue感興趣的同學(xué),可以參考下
    2021-05-05
  • 使用vux實(shí)現(xiàn)上拉刷新功能遇到的坑

    使用vux實(shí)現(xiàn)上拉刷新功能遇到的坑

    最近公司在研發(fā)app,選擇了基于Vue框架的vux組件庫,現(xiàn)總結(jié)在實(shí)現(xiàn)上拉刷新功能遇到的坑,感興趣的朋友參考下吧
    2018-02-02
  • 詳解vue中在循環(huán)中使用@mouseenter 和 @mouseleave事件閃爍問題解決方法

    詳解vue中在循環(huán)中使用@mouseenter 和 @mouseleave事件閃爍問題解決方法

    這篇文章主要介紹了詳解vue中在循環(huán)中使用@mouseenter 和 @mouseleave事件閃爍問題解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 基于Vue3實(shí)現(xiàn)SSR(服務(wù)端渲染)功能

    基于Vue3實(shí)現(xiàn)SSR(服務(wù)端渲染)功能

    在現(xiàn)代網(wǎng)頁開發(fā)中,用戶體驗(yàn)日益成為網(wǎng)站成功的重要因素,從加載時(shí)間到SEO優(yōu)化,越來越多的開發(fā)者開始關(guān)注使用服務(wù)端渲染(SSR)來提升應(yīng)用的表現(xiàn),本文將深入探討 Vue 3 的 SSR 特性,并以示例代碼展示如何實(shí)現(xiàn)這一功能,需要的朋友可以參考下
    2024-11-11
  • VueCli生產(chǎn)環(huán)境打包部署跨域失敗的解決

    VueCli生產(chǎn)環(huán)境打包部署跨域失敗的解決

    這篇文章主要介紹了VueCli生產(chǎn)環(huán)境打包部署跨域失敗的解決,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評論