色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

簡單介紹一下Vue中的響應(yīng)式原理

OSC開源社區(qū) ? 來源:OSCHINA 社區(qū) ? 2023-03-13 10:11 ? 次閱讀

自從 Vue 發(fā)布以來,就受到了廣大開發(fā)人員的青睞,提到 Vue,我們首先想到的就是 Vue 的響應(yīng)式系統(tǒng),那響應(yīng)式系統(tǒng)到底是怎么回事呢?接下來我就給大家簡單介紹一下 Vue 中的響應(yīng)式原理。

vue2 的響應(yīng)式原理

盡管 Vue2 將于 2023 年 12 月 31 日停止維護(hù),但是我們依然有很多項(xiàng)目是基于 Vue2.X 進(jìn)行開發(fā)的,那么我們先簡單看一看 Vue2.X 是基于什么實(shí)現(xiàn)的吧~

Object.defineProperty

Vue2 的響應(yīng)式原理是基于對象的 defineProperty () 方法進(jìn)行開發(fā)的,那么這個(gè)方法有什么作用呢?MDN 是這樣介紹的:

object.defineProperty () 方法會直接在一個(gè)對象上定義一個(gè)新屬性,或者修改一個(gè)對象的現(xiàn)有屬性,并返回此對象。

也就是說,我們可以通過對象的這個(gè)方法精確的添加或者修改對象的屬性。每個(gè)對象都具有 get/set 屬性,當(dāng)訪問 get 屬性時(shí),會調(diào)用 getter 方法,當(dāng)對象的屬性值被修改時(shí),會調(diào)用 setter 方法,正式基于 getter 和 setter 方法,Vue 才可以利用 Object.defineProperty 來實(shí)現(xiàn)響應(yīng)式系統(tǒng)。

Object.defineProperty 在 Vue 中的使用

在 vue 中,當(dāng)把一個(gè)普通的 JavaScript 對象傳入 Vue 實(shí)例作為 data 選項(xiàng),Vue 會遍歷此對象的所有屬性,并使用 object.defineProperty 將這些屬性轉(zhuǎn)為 getter/setter, getter/setter 可以追蹤依賴,在屬性被訪問的時(shí)候通知視圖變更。

Object.defineProperty(obj, 'targetObj', {
   get() {
     // 完成依賴收集
   },
   set() {
      // 發(fā)生變更,同時(shí)通知相關(guān)依賴
   }
})

vue3 的響應(yīng)式原理

vue2.0 很好的實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定,但是也遺留了一個(gè)很重要的問題:由于 Vue 會在初始化實(shí)例時(shí)將 property 轉(zhuǎn)化為 getter/setter,所以,property 必須在 data 對象上先存在才能讓 Vue 將其轉(zhuǎn)換為響應(yīng)式數(shù)據(jù)。

那么對于新增加的對象、或者某些需要特殊操作的數(shù)組想要轉(zhuǎn)換為響應(yīng)式數(shù)據(jù)就需要使用 Vue.set 等方法。 Vue3 就很好的解決了這個(gè)問題。那么,Vue3 是如何解決的呢?讓我們就一起看看吧~

Proxy

提到 Vue3 的數(shù)據(jù)攔截,我們首先要了解什么是 proxy?

Proxy 可以理解成,在目標(biāo)對象之前架設(shè)一層 “攔截”,外界對該對象的訪問,都必須先通過這層攔截,因此提供了一種機(jī)制,可以對外界的訪問進(jìn)行過濾和改寫。Proxy 這個(gè)詞的原意是代理,用在這里表示由它來 “代理” 某些操作,可以譯為 “代理器”。

原來,Vue3 用了 Proxy 代理代替了 Object.defineProperty 方法。同樣的,在 proxy 中也有 get/set 方法,舉個(gè)例子~

var obj = new Proxy({}, {
  get: function (target, name) {
    return name;
  },
  set: function (target, key, val) {
    target[key] = val
    return target;
  }
});
我們通過給每一個(gè)目標(biāo)對象都建立一個(gè)對應(yīng)的 Proxy 對象對其代理就可以彌補(bǔ) Object.defineProperty 對于新增對象無法監(jiān)聽的缺陷。

簡單設(shè)計(jì)一個(gè) Vue3 的響應(yīng)系統(tǒng)

實(shí)現(xiàn)一個(gè)簡單的響應(yīng)系統(tǒng)的思路: ?讀取(get)時(shí),將副作用函數(shù)入棧; ?設(shè)置(set)時(shí),將副作用函數(shù)出棧,執(zhí)行副作用函數(shù)。

// 存儲副作用函數(shù)的棧
const bucket = new Set()

// 存儲被注冊的副作用函數(shù)
let activeEffect

// 注冊副作用函數(shù)
functioneffect (fn) {
    // 存儲副作用函數(shù)
    activeEffect = fn
    fn()
}

// 副作用函數(shù)fn
effect (
    () => {
        document.body.innerText = obj.text
    }
)
執(zhí)行匿名函數(shù) fn 方法時(shí),會觸發(fā)響應(yīng)式數(shù)據(jù) obj.text 的讀取操作,進(jìn)而觸發(fā)代理對象 Proxy 的 get 攔截函數(shù):
const Proxy = new Proxy(data, {
    get (target, key) {
        if (activeEffect) {
            bucket.add(activeEffect)
        }
        return target[key]
    },
    set (target, key, newVal) {
        target[key] = newVal
        bucket.forEach(fn => fn())
        return true
    }
})
到此,我們會發(fā)現(xiàn),有一個(gè)疑問,我們怎樣能保證修改一個(gè)屬性之后觸發(fā)的副作用函數(shù)是我預(yù)期想要觸發(fā)的副作用函數(shù)呢?為了解決這個(gè)問題,我們還需要建立副作用函數(shù)與目標(biāo)對象的聯(lián)系: 我們僅需要用 WeakMap 代替 Set 數(shù)據(jù)結(jié)構(gòu):
const bucket = new WeakMap()

修改 Proxy 對象:

const Proxy = new Proxy(data, { 
    get (target, key) { 
        if (!activeEffect) return target[key]
        // 先從棧中取出depsMap,depsMap中保存目標(biāo)對象和其相關(guān)副作用函數(shù)的一對多的關(guān)系        
        let depsMap = bucket.get(target)
        if (!depsMap) {
            bucket.set(target, (depsMap = new Map())
        }
        // 再根據(jù)key從depsMap中取得deps,deps保存所有與key相關(guān)聯(lián)的副作用函數(shù)
        let deps = depsMap.get(key)
        if (!deps) {
            depsMap.set(key, (deps = new Set())
        }
        deps.add(activeEffect)
        
        return target[key] 
    }, 
    set (target, key, newVal) { 
        target[key] = newVal 
        const depsMap = bucket.get(target)
        if (!depsMap) return
        const effects = depsMap.get(key)
        effects && effects.forEach(fn => fn())  
    } 
})
這樣,我們就實(shí)現(xiàn)了一個(gè)簡易的響應(yīng)系統(tǒng)。那么為什么要用 weakMap 而不是使用 Map 呢?就交給大家一起思考啦~





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • vue
    vue
    +關(guān)注

    關(guān)注

    0

    文章

    58

    瀏覽量

    7851

原文標(biāo)題:初識 VUE 響應(yīng)式原理

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux搭建Vue開發(fā)環(huán)境

    本文介紹在Linux環(huán)境從零開始搭建Vue開發(fā)環(huán)境的整個(gè)過程,包括vue的安裝,webstorm 安裝配置,devtools的安裝。
    發(fā)表于 07-24 06:20

    vue簡單操作

    VUE】2編寫自己的第個(gè)模板頁面、跳轉(zhuǎn)以及簡單的axios請求
    發(fā)表于 10-15 09:17

    vue中會用的插件介紹

    vue:相關(guān)插件介紹
    發(fā)表于 03-17 11:30

    vue-cli-----vue實(shí)例template:'<App/>是什么意思?

    哪位大神知道vue-cli-----vue實(shí)例template:'是什么意思嗎?
    發(fā)表于 11-05 07:02

    簡單介紹一下ADC

    簡單介紹一下ADC:STM32F103 擁有 1~3 個(gè) ADC(STM32F101/102 系列只有 1 個(gè) ADC),這些 ADC 可以獨(dú)立使用,也可以使用雙重模式(提高采樣率)。 STM32
    發(fā)表于 08-12 07:07

    介紹一下一簡單易用的嵌入AI方案

    公司玩了大半年的嵌入AI平臺,現(xiàn)在產(chǎn)品進(jìn)入量產(chǎn)模式,也接觸了很多嵌入方案,有了些心得體會,本人不才,在這里介紹一下一
    發(fā)表于 10-27 06:02

    簡單分享一下Arduino程序編寫

    編寫程序代碼,然后我們將程序傳到Arduino電路板上,我們自己寫的程序會告訴電路板我們想要做的事情,因此,被許多電子愛好者(dalao)所喜愛。最近簡單了解了一下Arduino程序編寫,
    發(fā)表于 01-07 08:14

    整理一下ElementUI+VUE日期控件禁用用法

    今天給大家整理一下ElementUI+VUE 日期控件禁用用法,希望對大家有所幫助!HTML文件
    發(fā)表于 01-18 09:35

    關(guān)于vue如何去水印的解決方法的介紹

    很多人都懂簡單的電腦系統(tǒng)問題的解決方案,但是vue怎么去水印的解決思路卻鮮為人知,小編前幾天就遇到了vue怎么去水印的問題,于是準(zhǔn)備整理
    發(fā)表于 03-24 17:33 ?3426次閱讀

    Vue入門之Vue定義

    Vue (讀音 /vju?/,類似于 view) 是套用于構(gòu)建用戶界面的漸進(jìn)JavaScript框架。 Vue 的核心庫只關(guān)注視圖層,也就是只處理頁面。
    的頭像 發(fā)表于 02-06 16:41 ?1096次閱讀
    <b class='flag-5'>Vue</b>入門之<b class='flag-5'>Vue</b>定義

    如何使用springboot+vue搭建個(gè)人網(wǎng)站3

    Vue.js(讀音 /vju?/, 類似于 view)是個(gè)構(gòu)建數(shù)據(jù)驅(qū)動的 web 界面的漸進(jìn)框架。Vue現(xiàn)在這么火,大家都懂。接下來讓我們來認(rèn)識
    的頭像 發(fā)表于 02-14 16:05 ?1339次閱讀
    如何使用springboot+<b class='flag-5'>vue</b>搭建個(gè)人網(wǎng)站3

    簡單介紹一下什么是微波通訊?

    歡迎來到東用知識小課堂,今天東東就為大家簡單介紹一下什么是微波通訊?我們通常說有三大傳輸系統(tǒng):光纖通信、微波通信、衛(wèi)星通信。實(shí)際上,衛(wèi)星通信也是微波通信的種。通俗的講電磁波通信,主要
    的頭像 發(fā)表于 03-05 11:33 ?2348次閱讀
    <b class='flag-5'>簡單</b><b class='flag-5'>介紹</b><b class='flag-5'>一下</b>什么是微波通訊?

    文看懂Vue3響應(yīng)系統(tǒng)原理

    Vue3 響應(yīng)系統(tǒng)的實(shí)現(xiàn)基于 ES6 的 Proxy 對象。Proxy 可以直接監(jiān)聽對象和數(shù)組的變化,而無需對每個(gè)屬性進(jìn)行監(jiān)聽,從而大大提高性能。同時(shí),Proxy 也可以解決
    的頭像 發(fā)表于 12-07 10:55 ?1748次閱讀
    <b class='flag-5'>一</b>文看懂<b class='flag-5'>Vue</b>3<b class='flag-5'>響應(yīng)</b><b class='flag-5'>式</b>系統(tǒng)原理

    簡單介紹一下電源紋波與電容嘯叫

    簡單介紹一下電源紋波與電容嘯叫? 電源紋波與電容嘯叫是在電源系統(tǒng)中常見的兩種問題,它們會影響電子設(shè)備的性能和穩(wěn)定性。本篇文章將詳細(xì)介紹電源紋波和電容嘯叫的定義、原因、對設(shè)備的影響以及常
    的頭像 發(fā)表于 02-04 09:42 ?1074次閱讀

    Vue3設(shè)計(jì)思想及響應(yīng)源碼剖析

    作者:京東物流 喬盼盼 Vue3結(jié)構(gòu)分析 1、Vue2與Vue3的對比 ?對TypeScript支持不友好(所有屬性都放在了this對象上,難以推倒組件的數(shù)據(jù)類型) ?大量的API
    的頭像 發(fā)表于 12-20 10:24 ?126次閱讀
    主站蜘蛛池模板: 2019午夜福利757视频第12集| 亚洲AV日韩AV欧美在线观看网| 国产成人免费片在线视频观看| 99久久蜜臀AV免费看蛮| 伊人久久大香线蕉综合99| 羞羞漫画视频| 无人区乱码1区2区3区网站| 日本另类xxxx| 人人舔人人爱| 日日夜夜国产| 色尼玛亚洲综合| 射90黑b丝女| 小p孩玩成年女性啪啪资源| 先锋资源久久| 亚洲第一伊人| 亚洲视频成人| 在线观看中文字幕国产| 中文字幕视频免费在线观看| 18美女腿打开无遮软件| 97人摸人人澡人人人超一碰| 97国产精品久久精品国产| 99视频精品全部 国产| 补课H湿 1V1 PLAY| 囯产精品久久久久久久久免费蜜桃 | 忘忧草秋观看未满十八| 无码爽死成人777在线观看网站 | 拔萝卜在线高清观看视频| 不良网站进入窗口软件下载免费| 成人高清网站| 国产精品无需播放器| 黑人巨茎大战白人女40CMO| 久久精品国产亚洲AV未满十八 | 免费在线观看的毛片| 强奷乱码欧妇女中文字幕熟女| 日本漫画之无彩翼漫画| 视频成人永久免费视频| 亚洲精品国偷拍自产在线| 欲香欲色天天影视大全| 2019久久视频这里有精品15| ppypp日本欧美一区二区| 国产传媒在线播放|