国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

深入理解Vue Computed計算屬性原理

2024-05-06 15:33:48
字體:
來源:轉載
供稿:網友

Computed 計算屬性是 Vue 中常用的一個功能,但你理解它是怎么工作的嗎?

拿官網簡單的例子來看一下:

<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p></div>
var vm = new Vue({ el: '#example', data: {  message: 'Hello' }, computed: {  // a computed getter  reversedMessage: function () {   // `this` points to the vm instance   return this.message.split('').reverse().join('')  } }})

Situation

Vue 里的 Computed 屬性非常頻繁的被使用到,但并不是很清楚它的實現(xiàn)原理。比如:計算屬性如何與屬性建立依賴關系?屬性發(fā)生變化又如何通知到計算屬性重新計算?

關于如何建立依賴關系,我的第一個想到的就是語法解析,但這樣太浪費性能,因此排除,第二個想到的就是利用 JavaScript 單線程的原理和 Vue 的 Getter 設計,通過一個簡單的發(fā)布訂閱,就可以在一次計算屬性求值的過程中收集到相關依賴。

因此接下來的任務就是從 Vue 源碼一步步分析 Computed 的實現(xiàn)原理。

Task

分析依賴收集實現(xiàn)原理,分析動態(tài)計算實現(xiàn)原理。

Action

data 屬性初始化 getter setter:

// src/observer/index.js// 這里開始轉換 data 的 getter setter,原始值已存入到 __ob__ 屬性中Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () {  const value = getter ? getter.call(obj) : val  // 判斷是否處于依賴收集狀態(tài)  if (Dep.target) {   // 建立依賴關系   dep.depend()   ...  }  return value }, set: function reactiveSetter (newVal) {  ...  // 依賴發(fā)生變化,通知到計算屬性重新計算  dep.notify() }})

computed 計算屬性初始化

// src/core/instance/state.js// 初始化計算屬性function initComputed (vm: Component, computed: Object) { ... // 遍歷 computed 計算屬性 for (const key in computed) {  ...  // 創(chuàng)建 Watcher 實例  // create internal watcher for the computed property.  watchers[key] = new Watcher(vm, getter || noop, noop, computedWatcherOptions)  // 創(chuàng)建屬性 vm.reversedMessage,并將提供的函數(shù)將用作屬性 vm.reversedMessage 的 getter,  // 最終 computed 與 data 會一起混合到 vm 下,所以當 computed 與 data 存在重名屬性時會拋出警告  defineComputed(vm, key, userDef)  ... }}export function defineComputed (target: any, key: string, userDef: Object | Function) { ... // 創(chuàng)建 get set 方法 sharedPropertyDefinition.get = createComputedGetter(key) sharedPropertyDefinition.set = noop ... // 創(chuàng)建屬性 vm.reversedMessage,并初始化 getter setter Object.defineProperty(target, key, sharedPropertyDefinition)}function createComputedGetter (key) { return function computedGetter () {  const watcher = this._computedWatchers && this._computedWatchers[key]  if (watcher) {   if (watcher.dirty) {    // watcher 暴露 evaluate 方法用于取值操作    watcher.evaluate()   }   // 同第1步,判斷是否處于依賴收集狀態(tài)   if (Dep.target) {    watcher.depend()   }   return watcher.value  } }}            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 杨浦区| 平安县| 任丘市| 大埔县| 绿春县| 碌曲县| 封丘县| 龙江县| 邢台市| 武山县| 辉县市| 正镶白旗| 微博| 榆中县| 都昌县| 伊宁市| 西吉县| 新丰县| 哈尔滨市| 湘阴县| 通化县| 象州县| 兴义市| 吉安市| 阜平县| 迭部县| 临沧市| 扶风县| 桃源县| 汉川市| 巩留县| 三江| 昭平县| 中方县| 当涂县| 东乌| 临泉县| 乐安县| 菏泽市| 保山市| 靖安县|