日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)VUE3教程:Vue 3.0 響應(yīng)性 深入響應(yīng)性原理

現(xiàn)在是時(shí)候深入了!Vue 最獨(dú)特的特性之一,是其非侵入性的響應(yīng)性系統(tǒng)。數(shù)據(jù)模型是被代理的 JavaScript 對象。而當(dāng)你修改它們時(shí),視圖會進(jìn)行更新。這讓狀態(tài)管理非常簡單直觀,不過理解其工作原理同樣重要,這樣你可以避開一些常見的問題。在這個(gè)章節(jié),我們將研究一下 Vue 響應(yīng)性系統(tǒng)的底層的細(xì)節(jié)。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了貴港免費(fèi)建站歡迎大家使用!

在 Vue Mastery 上免費(fèi)觀看關(guān)于深入響應(yīng)性原理的視頻。

#什么是響應(yīng)性

這個(gè)術(shù)語在程序設(shè)計(jì)中經(jīng)常被提及,但這是什么意思呢?響應(yīng)性是一種允許我們以聲明式的方式去適應(yīng)變化的一種編程范例。人們通常展示的典型例子,是一份 excel 電子表格 (一個(gè)非常好的例子)。

點(diǎn)擊此處看視頻

如果將數(shù)字 2 放在第一個(gè)單元格中,將數(shù)字 3 放在第二個(gè)單元格中并要求提供 SUM,則電子表格會將其計(jì)算出來給你。不要驚奇,同時(shí),如果你更新第一個(gè)數(shù)字,SUM 也會自動(dòng)更新。

JavaScript 通常不是這樣工作的——如果我們想用 JavaScript 編寫類似的內(nèi)容:

var val1 = 2
var val2 = 3
var sum = val1 + val2


// sum
// 5


val1 = 3


// sum
// 5

如果我們更新第一個(gè)值,sum 不會被修改。

那么我們?nèi)绾斡?JavaScript 實(shí)現(xiàn)這一點(diǎn)呢?

  • 檢測其中某一個(gè)值是否發(fā)生變化
  • 用跟蹤 (track) 函數(shù)修改值
  • 用觸發(fā) (trigger) 函數(shù)更新為最新的值

#Vue 如何追蹤變化?

當(dāng)把一個(gè)普通的 JavaScript 對象作為 data 選項(xiàng)傳給應(yīng)用或組件實(shí)例的時(shí)候,Vue 會使用帶有 getter 和 setter 的處理程序遍歷其所有 property 并將其轉(zhuǎn)換為 Proxy。這是 ES6 僅有的特性,但是我們在 Vue 3 版本也使用了 Object.defineProperty 來支持 IE 瀏覽器。兩者具有相同的 Surface API,但是 Proxy 版本更精簡,同時(shí)提升了性能。

點(diǎn)擊此處實(shí)現(xiàn)

該部分需要稍微地了解下 Proxy 的某些知識!所以,讓我們深入了解一下。關(guān)于 Proxy 的文獻(xiàn)很多,但是你真正需要知道的是 Proxy 是一個(gè)包含另一個(gè)對象或函數(shù)并允許你對其進(jìn)行攔截的對象。

我們是這樣使用它的:new Proxy(target, handler)

const dinner = {
  meal: 'tacos'
}


const handler = {
  get(target, prop) {
    return target[prop]
  }
}


const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)


// tacos

好的,到目前為止,我們只是包裝這個(gè)對象并返回它。很酷,但還不是那么有用。請注意,我們把對象包裝在 Proxy 里的同時(shí)可以對其進(jìn)行攔截。這種攔截被稱為陷阱。

const dinner = {
  meal: 'tacos'
}


const handler = {
  get(target, prop) {
    console.log('intercepted!')
    return target[prop]
  }
}


const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)


// tacos

除了控制臺日志,我們可以在這里做任何我們想做的事情。如果我們愿意,我們甚至可以不返回實(shí)際值。這就是為什么 Proxy 對于創(chuàng)建 API 如此強(qiáng)大。

此外,Proxy 還提供了另一個(gè)特性。我們不必像這樣返回值:target[prop],而是可以進(jìn)一步使用一個(gè)名為 Reflect 的方法,它允許我們正確地執(zhí)行 this 綁定,就像這樣:

const dinner = {
  meal: 'tacos'
}


const handler = {
  get(target, prop, receiver) {
    return Reflect.get(...arguments)
  }
}


const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)


// tacos

我們之前提到過,為了有一個(gè) API 能夠在某些內(nèi)容發(fā)生變化時(shí)更新最終值,我們必須在內(nèi)容發(fā)生變化時(shí)設(shè)置新的值。我們在處理器,一個(gè)名為 track 的函數(shù)中執(zhí)行此操作,該函數(shù)可以傳入 targetkey 兩個(gè)參數(shù)。

const dinner = {
  meal: 'tacos'
}


const handler = {
  get(target, prop, receiver) {
    track(target, prop)
    return Reflect.get(...arguments)
  }
}


const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)


// tacos

最后,當(dāng)某些內(nèi)容發(fā)生改變時(shí)我們會設(shè)置新的值。為此,我們將通過觸發(fā)這些更改來設(shè)置新 Proxy 的更改:

const dinner = {
  meal: 'tacos'
}


const handler = {
  get(target, prop, receiver) {
    track(target, prop)
    return Reflect.get(...arguments)
  },
  set(target, key, value, receiver) {
    trigger(target, key)
    return Reflect.set(...arguments)
  }
}


const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)


// tacos

還記得幾段前的列表嗎?現(xiàn)在我們有了一些關(guān)于 Vue 如何處理這些更改的答案:

  • 當(dāng)某個(gè)值發(fā)生變化時(shí)進(jìn)行檢測:我們不再需要這樣做,因?yàn)?Proxy 允許我們攔截它
  • 跟蹤更改它的函數(shù):我們在 Proxy 中的 getter 中執(zhí)行此操作,稱為 effect
  • 觸發(fā)函數(shù)以便它可以更新最終值:我們在 Proxy 中的 setter 中進(jìn)行該操作,名為 trigger

Proxy 對象對于用戶來說是不可見的,但是在內(nèi)部,它們使 Vue 能夠在 property 的值被訪問或修改的情況下進(jìn)行依賴跟蹤和變更通知。從 Vue 3 開始,我們的響應(yīng)性現(xiàn)在可以在獨(dú)立的包中使用。需要注意的是,記錄轉(zhuǎn)換后的數(shù)據(jù)對象時(shí),瀏覽器控制臺輸出的格式會有所不同,因此你可能需要安裝 vue-devtools,以提供一種更易于檢查的界面。

#Proxy 對象

Vue 在內(nèi)部跟蹤所有已被設(shè)置為響應(yīng)式的對象,因此它始終會返回同一個(gè)對象的 Proxy 版本。

從響應(yīng)式 Proxy 訪問嵌套對象時(shí),該對象在返回之前被轉(zhuǎn)換為 Proxy:

const handler = {
  get(target, prop, receiver) {
    track(target, prop)
    const value = Reflect.get(...arguments)
    if (isObject(value)) {
      return reactive(value)
    } else {
      return value
    }
  }
  // ...
}

#Proxy vs 原始標(biāo)識

Proxy 的使用確實(shí)引入了一個(gè)需要注意的新警告:在身份比較方面,被代理對象與原始對象不相等 (===)。例如:

const obj = {}
const wrapped = new Proxy(obj, handlers)


console.log(obj === wrapped) // false

在大多數(shù)情況下,原始版本和包裝版本的行為相同,但請注意,它們在依賴嚴(yán)格比對的操作下將是失敗的,例如 .filter().map()。使用選項(xiàng)式 API 時(shí),這種警告不太可能出現(xiàn),因?yàn)樗许憫?yīng)式都是從 this 訪問的,并保證已經(jīng)是 Proxy。

但是,當(dāng)使用合成 API 顯式創(chuàng)建響應(yīng)式對象時(shí),最佳做法是不要保留對原始對象的引用,而只使用響應(yīng)式版本:

const obj = reactive({
  count: 0
}) // no reference to original

#偵聽器

每個(gè)組件實(shí)例都有一個(gè)相應(yīng)的偵聽器實(shí)例,該實(shí)例將在組件渲染期間把“觸碰”的所有 property 記錄為依賴項(xiàng)。之后,當(dāng)觸發(fā)依賴項(xiàng)的 setter 時(shí),它會通知偵聽器,從而使得組件重新渲染。

點(diǎn)擊此處實(shí)現(xiàn)

將對象作為數(shù)據(jù)傳遞給組件實(shí)例時(shí),Vue 會將其轉(zhuǎn)換為 Proxy。這個(gè) Proxy 使 Vue 能夠在 property 被訪問或修改時(shí)執(zhí)行依賴項(xiàng)跟蹤和更改通知。每個(gè) property 都被視為一個(gè)依賴項(xiàng)。

首次渲染后,組件將跟蹤一組依賴列表——即在渲染過程中被訪問的 property。反過來,組件就成為了其每個(gè) property 的訂閱者。當(dāng) Proxy 攔截到 set 操作時(shí),該 property 將通知其所有訂閱的組件重新渲染。

如果你使用的是 Vue2.x 及以下版本,你可能會對這些版本中存在的一些更改檢測警告感興趣,在這里進(jìn)行更詳細(xì)的探討。


分享標(biāo)題:創(chuàng)新互聯(lián)VUE3教程:Vue 3.0 響應(yīng)性 深入響應(yīng)性原理
標(biāo)題URL:http://m.5511xx.com/article/ccdcejc.html