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

Vue3中watch監(jiān)聽(tīng)器及源碼學(xué)習(xí)

 更新時(shí)間:2024年01月21日 11:40:24   作者:Unique·Blue  
本文主要介紹了Vue3中watch監(jiān)聽(tīng)器及源碼學(xué)習(xí),Watch偵聽(tīng)器在Vue3中特性進(jìn)行了一些改變和優(yōu)化,下面來(lái)詳解的介紹一下基本使用,具有一定的參考價(jià)值,感興趣的可以了解一下

示例均采用 <script setup>,且包含 typescript 的基礎(chǔ)用法

前言

在 vue3 中,必須是 ref、reactive 包裹起來(lái)的數(shù)據(jù),才可以被 watch 監(jiān)聽(tīng)到

一、基本使用

1、語(yǔ)法:watch(source, cb, options)

  • source 是監(jiān)聽(tīng)的目標(biāo),有 4 種書(shū)寫(xiě)形式:
    • reactive 形式的響應(yīng)式數(shù)據(jù)
    • ref 形式的響應(yīng)式數(shù)據(jù)
    • 數(shù)組形式:監(jiān)聽(tīng)多個(gè)響應(yīng)式數(shù)據(jù)時(shí)(應(yīng)該用的不多)
      • 挨個(gè)放進(jìn) 數(shù)組 里,如 [響應(yīng)式數(shù)據(jù)1, 響應(yīng)式數(shù)據(jù)2]
      • cb 對(duì)應(yīng)的 函數(shù)參數(shù)(新值、舊值)也都是 數(shù)組 形式,詳見(jiàn)例子
    • 函數(shù)形式:若只想監(jiān)聽(tīng) reactive 深層中 的 指定屬性,該指定屬性是
      • 引用類(lèi)型,不需要函數(shù)形式,直接 obj.a.b
      • 非引用類(lèi)型,比如是一個(gè)字符串,則需要使用 函數(shù)形式 返回,詳見(jiàn)例子
  • cb 是回調(diào)函數(shù),(newVal,oldVal) => {}
  • options 是配置項(xiàng)
    • deep: 是否開(kāi)啟深層監(jiān)聽(tīng)
      • reactive 類(lèi)型的數(shù)據(jù) 不需要開(kāi)啟,源碼中已做了深層響應(yīng)式
      • ref 類(lèi)型的數(shù)據(jù)如果需要監(jiān)聽(tīng)到深層,要設(shè)置為 true(雖然監(jiān)聽(tīng)到深層,但是 source 不能指定到深層)
    • immediate: 是否立刻執(zhí)行
    • flush: watch 的執(zhí)行順序。
      • pre 組件更新之前執(zhí)行(默認(rèn))
      • sync 同步執(zhí)行;
      • post 組件更新之后執(zhí)行

2、例子

下面代碼中,演示了多個(gè)情景下的使用

<input type="text" v-model="xiaoman1" />
<br />
<input type="text" v-model="xiaoman2" />
<br />
<input type="text" v-model="message.foo.bar" />
<br />
<input type="text" v-model="message2.foo.bar" />
const xiaoman1 = ref<string>("小滿1");
const xiaoman2 = ref<string>("小滿2");

const message = ref({
  foo: {
    bar: "aaaaa",
  },
});

const message2 = reactive({
  foo: {
    bar: "aaaaa",
  },
});

watch(xiaoman1, (newVal, oldVal) => {
  console.log("監(jiān)聽(tīng)單個(gè)數(shù)據(jù)源", newVal, oldVal);
});

// 用數(shù)組監(jiān)聽(tīng)多個(gè)數(shù)據(jù)源,[新值數(shù)組], [舊值數(shù)組]
watch([xiaoman1, xiaoman2], (newVal, oldVal) => {
  console.log("用數(shù)組監(jiān)聽(tīng)多個(gè)數(shù)據(jù)源,[新值數(shù)組], [舊值數(shù)組]", newVal, oldVal);
});

// ref 深層監(jiān)聽(tīng)
watch(
  message,
  (newVal, oldVal) => {
    // 如果是引用類(lèi)型,新值 和 舊值 是一樣的
    console.log("ref 深層監(jiān)聽(tīng)&立刻執(zhí)行", newVal, oldVal);
  },
  {
    deep: true, // 深度監(jiān)聽(tīng),ref 若需要深度監(jiān)聽(tīng),這里要開(kāi)啟
    immediate: true, // callback 立刻先執(zhí)行一次
    flush: "pre", // 【watch的執(zhí)行順序】 pre 組件更新之前調(diào)用(默認(rèn));sync 同步執(zhí)行;post 組件更新之后執(zhí)行
    // flush 屬性在 watch 中用的不多,watchEffect中可能用到
  }
);

// reactive 深層監(jiān)聽(tīng):不必開(kāi)啟深度監(jiān)聽(tīng)
watch(
  message2,
  (newVal, oldVal) => {
    // 如果是引用類(lèi)型,新值 和 舊值 是一樣的
    console.log("reactive 深層監(jiān)聽(tīng)&立刻執(zhí)行", newVal, oldVal);
  },
  {
    // deep: true, // reactive 不必開(kāi)啟深度監(jiān)聽(tīng),源碼已做了深層監(jiān)聽(tīng)
    // immediate: true,
  }
);

// 若只想監(jiān)聽(tīng) reactive 深層中的單個(gè)屬性,(第一個(gè)參數(shù))引用類(lèi)型可直接寫(xiě),否則使用函數(shù)形式
watch(
  message2.foo, // 監(jiān)聽(tīng)到 foo,foo是引用類(lèi)型,直接寫(xiě)就行
  // () => message2.foo.bar, // 監(jiān)聽(tīng)到 bar,需要用函數(shù)形式

  (newVal, oldVal) => {
    // 如果是引用類(lèi)型,新值 和 舊值 是一樣的
    console.log("reactive 監(jiān)聽(tīng)深層中的單個(gè)屬性", newVal, oldVal);
  }
);

二、源碼學(xué)習(xí)

由于源碼較多,這里不做截圖

/**
 * 

 * @vue/runtime-core/runtime-core.cjs.prod.js 搜索 function watch
 *
 * -  watch(source, cb, options)
 *
 * -  source 有很多種類(lèi)型,reactive、ref、數(shù)組、函數(shù),所以先判斷類(lèi)型,格式化source
 *    - ref 類(lèi)型,直接把 value 取出來(lái),賦值給 getter
 *    - reactive 類(lèi)型,直接把整體賦值給 getter,deep 手動(dòng)置為 true 即可(reactive已經(jīng)進(jìn)行了深度監(jiān)聽(tīng))
 *    - 數(shù)組類(lèi)型,做遍歷,對(duì)每一項(xiàng)再判斷類(lèi)型,分別處理完之后丟進(jìn)新數(shù)組返回
 *          - ref類(lèi)型,返回.value
 *          - reactive類(lèi)型,遞歸處理后返回
 *          - 函數(shù)的話,進(jìn)行加工
 *    - 函數(shù)類(lèi)型
 *          - 判斷有沒(méi)有 cb
 *              - 有 cb 的話,同樣也是對(duì)函數(shù)做了加工賦值給 getter
 *              - 沒(méi)有 cb,走進(jìn) watchEffect(下一章)
 *
 * - deep處理:
 *          - cb、deep 若同時(shí)存在,即 有回調(diào)函數(shù) 且設(shè)置了 深度監(jiān)聽(tīng),進(jìn)行 traverse 遞歸深度監(jiān)聽(tīng)(當(dāng)然是更耗時(shí)的)
 *
 * - flush處理:先初始化出 scheduler 調(diào)度器
 *          - sync 同步執(zhí)行,scheduler = job
 *          - post 組件更新后,將 job 通過(guò) queuePostRenderEffect 函數(shù)處理后再賦值給 scheduler
 *                  - 注意,源碼中看到 queuePostRenderEffect 這個(gè)函數(shù),一定表示是在組件更新之后再去執(zhí)行
 *          - pre 組件更新前,queueJob 處理 job 后賦值給 scheduler
 *
 * - ReactiveEffect 收集依賴(lài)更新:
 *          - 上面步驟 將 getter、scheduler處理好后作為參數(shù) 給到 ReactiveEffect 函數(shù)
 *          - ReactiveEffect 收集好依賴(lài)之后,有更新的話 就會(huì)觸發(fā) scheduler,也就是說(shuō)會(huì)執(zhí)行 job
 *
 *
 * - cb 存在
 *          - immediate 為 true 時(shí),會(huì)立即調(diào)用一下 job
 *                - 內(nèi)部會(huì)先獲取到新值 newVal
 *                - 如果是第一次執(zhí)行,舊值 oldVal 會(huì)置為 undefined
 *                - (執(zhí)行完這里才會(huì)更新)然后 把新值賦值給舊值,為下一次使用準(zhǔn)備 (所以如果是對(duì)象,新舊值是相等的)
 *          - immediate 為 false 時(shí),
 *                - 先給舊值做初始化,如 oldVal = '小滿'
 *                - 依賴(lài)如果更新,會(huì)觸發(fā) scheduler,執(zhí)行 job
 *                      - job 內(nèi)新值 newVal = '小滿1'
 *                      - 舊值 oldVal 不會(huì)走進(jìn) undefined,會(huì)等于原有的 oldVal = '小滿'
 *                      - (執(zhí)行完這里才會(huì)更新)會(huì)把 oldVal = '小滿1'
 *
 *
 */

到此這篇關(guān)于Vue3中watch監(jiān)聽(tīng)器及源碼學(xué)習(xí)的文章就介紹到這了,更多相關(guān)Vue3中watch監(jiān)聽(tīng)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Vue?2?和?Vue?3?中?toRefs函數(shù)的不用用法

    Vue?2?和?Vue?3?中?toRefs函數(shù)的不用用法

    Vue?是一款流行的JavaScript?框架,用于構(gòu)建用戶界面,在Vue2和?Vue3中,都存在一個(gè)名為toRefs的函數(shù),但其行為在這兩個(gè)版本中有所不同,這篇文章主要介紹了Vue2和Vue3中toRefs的區(qū)別,需要的朋友可以參考下
    2023-08-08
  • vuex學(xué)習(xí)進(jìn)階篇之getters的使用教程

    vuex學(xué)習(xí)進(jìn)階篇之getters的使用教程

    getters用于獲取state里的數(shù)據(jù),它類(lèi)似于計(jì)算屬性,如果要獲取的數(shù)據(jù)并沒(méi)有發(fā)生變化的話,就會(huì)返回緩存的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于vuex學(xué)習(xí)進(jìn)階篇之getters的使用教程,需要的朋友可以參考下
    2022-10-10
  • vue3項(xiàng)目中的el-carousel 輪播圖的使用

    vue3項(xiàng)目中的el-carousel 輪播圖的使用

    Carousel(走馬燈)是一種常見(jiàn)的前端組件,通常用于展示多個(gè)項(xiàng)目(通常是圖片或內(nèi)容塊)的輪播效果,這篇文章主要介紹了vue3項(xiàng)目中的el-carousel 輪播圖的使用,需要的朋友可以參考下
    2024-02-02
  • 淺談mint-ui loadmore組件注意的問(wèn)題

    淺談mint-ui loadmore組件注意的問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談mint-ui loadmore組件注意的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • vue實(shí)現(xiàn)移動(dòng)端適方案的完整步驟

    vue實(shí)現(xiàn)移動(dòng)端適方案的完整步驟

    現(xiàn)在的手機(jī)五花八門(mén),造就了移動(dòng)端窗口分辨率繁多的局面,在不同分辨率的屏幕下保持與UI圖一致的效果,就成了讓前端不得不頭疼的問(wèn)題,下面這篇文章主要給大家介紹了vue實(shí)現(xiàn)移動(dòng)端適方案的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • 談?wù)勎以趘ue-cli3中用預(yù)渲染遇到的坑

    談?wù)勎以趘ue-cli3中用預(yù)渲染遇到的坑

    這篇文章主要介紹了談?wù)勎以趘ue-cli3中用預(yù)渲染遇到的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • vue項(xiàng)目部署上線遇到的問(wèn)題及解決方法

    vue項(xiàng)目部署上線遇到的問(wèn)題及解決方法

    這篇文章主要介紹了vue項(xiàng)目部署上線遇到的問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2018-06-06
  • vue+element開(kāi)發(fā)使用el-select不能回顯的處理方案

    vue+element開(kāi)發(fā)使用el-select不能回顯的處理方案

    這篇文章主要介紹了vue+element開(kāi)發(fā)使用el-select不能回顯的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Vue學(xué)習(xí)筆記進(jìn)階篇之vue-router安裝及使用方法

    Vue學(xué)習(xí)筆記進(jìn)階篇之vue-router安裝及使用方法

    本篇文章主要介紹了Vue學(xué)習(xí)筆記進(jìn)階篇之vue-router安裝及使用方法,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • vue3 開(kāi)始時(shí)間與結(jié)束時(shí)間比較驗(yàn)證(結(jié)束時(shí)間需要大于開(kāi)始時(shí)間)

    vue3 開(kāi)始時(shí)間與結(jié)束時(shí)間比較驗(yàn)證(結(jié)束時(shí)間需要大于開(kāi)始時(shí)間)

    本文通過(guò)示例代碼介紹了vue3 開(kāi)始時(shí)間與結(jié)束時(shí)間比較驗(yàn)證(結(jié)束時(shí)間需要大于開(kāi)始時(shí)間)的相關(guān)操作,代碼簡(jiǎn)單易懂,感興趣的朋友跟隨小編一起看看吧
    2024-07-07

最新評(píng)論