摘要:前言源碼解析一模版渲染源碼解析二雙向綁定官網給出的如下結果源碼分析判斷參數是否包含屬性本例中本例中和是函數監聽計算屬性設置,延遲執行的方法設置可以通過本例方式訪問計算屬性對象初始化時會針對屬性的所有值分別一個對象,在源碼解析二中有詳細介
前言
1、Vue源碼解析(一)-模版渲染
2、Vue源碼解析(二)-MVVM雙向綁定
官網給出的demo如下
new Vue({ el: "#app", template: `源碼分析`, data(){ return { message: "Hello", } }, computed:{ reversedMessage(){ return this.message.split("").reverse().join("") } } }) 結果: Original message: "Hello" Computed reversed message: "olleH"Original message is: {{ message }}
Computed reversed message:: {{ reversedMessage }}
//判斷參數是否包含computed屬性 if (opts.computed) { initComputed(vm, opts.computed); } function initComputed (vm, computed) { var watchers = vm._computedWatchers = Object.create(null); //本例中key=‘reversedMessage’ for (var key in computed) { //本例中userDef和getter是reversedMessage函數 var userDef = computed[key]; var getter = typeof userDef === "function" ? userDef : userDef.get; //監聽計算屬性,設置lazy=true,延遲執行watcher的get方法 watchers[key] = new Watcher(vm,getter,{lazy:true}); //設置可以通過vm[key](本例vm.reversedMessage)方式訪問計算屬性 defineComputed(vm, key, userDef); } }
1、vue對象初始化時會針對computed屬性的所有key值分別new一個watcher對象,在Vue源碼解析(二)中有詳細介紹watcher的原理,當時提到watcher初始化會立即調用一次watcher.get方法,然后實際上可以通過傳入{lazy:true}參數來延遲watcher.get方法的執行
var Watcher = function Watcher (vm,expOrFn,options){ //延遲計算 this.lazy = options.lazy; //還沒有計算,所以數據是臟的 this.dirty = options.lazy; this.value = this.lazy ? undefined //計算getter值和收集依賴 : this.get(); }
2、defineComputed(vm, key, userDef),將computed屬性代理到vm上,通過vm[key]訪問computed屬性值
function defineComputed (target,key,userDef){ //userDef是function,getter設為userDef或userDef的值 if (typeof userDef === "function") { //shouldCache是否緩存,這也是使用computed屬性最重要的原因,computed值會被緩存起來,而不是每次重新執行函數生成 sharedPropertyDefinition.get = shouldCache ? createComputedGetter(key) : userDef; sharedPropertyDefinition.set = null; //userDef是不是function,getter設為userDef.get,setter設為userDef.set } else { sharedPropertyDefinition.get = userDef.get ? shouldCache && userDef.cache !== false ? createComputedGetter(key) : userDef.get : null; sharedPropertyDefinition.set = userDef.set ? userDef.set : null; } //,將computed屬性代理到vm上,通過vm[key]訪問computed屬性值 Object.defineProperty(target, key, sharedPropertyDefinition); } function createComputedGetter (key) { return function computedGetter () { //shouldCache = true時直接返回緩存值watcher.value var watcher = this._computedWatchers && this._computedWatchers[key]; //存在臟數據則重新計算watcher的值 if (watcher.dirty) { watcher.evaluate(); } //直接返回緩存中watcher的值 return watcher.value } } }
3、前面提到watcher.get方法會延遲執行,那么到底啥時執行呢?這又得提到Vue源碼解析(二)中的updateComponent方法,由于本例引用了計算屬性{{ reversedMessage }},updateComponent中的render函數則會調用vm.reversedMessage,因此觸發第二步的sharedPropertyDefinition.get函數,調用 watcher.evaluate(),最終調用watcher.get()來計算watcher的值和收集依賴。(watcher.get方法將監聽vm.reversedMessage的watcher對象和發布vm.message變化的dep對象綁定,因此當vm.message變化時,vm.reversedMessage值也會同步變化)
因此watcher.get是在第一次訪問vm.reversedMessage對象時調用的,所以如果模版沒有用到{{ reversedMessage }}值的話vm.reversedMessage的值是不會被計算的
/** * Evaluate the value of the watcher. * This only gets called for lazy watchers. */ Watcher.prototype.evaluate = function evaluate () { this.value = this.get(); this.dirty = false; };雙向綁定問題
正好之前看到過一個問題vue.js使用computed計算某個屬性后,該屬性的雙向綁定沒了,看了本文的源碼后大家應該了解了計算屬性用在v-model上應該設置setter方法,例如本例中demo應該這么寫:
new Vue({ el: "#app", template: ``, data(){ return { message: "jixiangwu", } }, computed:{ reversedMessage:{ get(){ return this.message.split("").reverse().join("") }, set(val){ this.message = val.split("").reverse().join("") } } } })Original message is: {{ message }}
Computed reversed message:: {{ reversedMessage }}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89612.html
摘要:被讀取,包裝的函數觸發,第一次會進行計算被調用,進而被調用,被設置為,舊值頁面被緩存起來。計算會讀取,此時就收集到同時也會保存到的依賴收集器用于下一步。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下...
摘要:并在內執行了函數,在函數內部,訪問了。至此知道了它依賴于。需要根據最新的計算。本例中收集到了依賴并且也被告知觀察了他們。文章鏈接源碼分析系列源碼分析系列之環境搭建源碼分析系列之入口文件分析源碼分析系列之響應式數據一源碼分析系列之響應式數據二 前言 上一節著重講述了initData中的代碼,以及數據是如何從data中到視圖層的,以及data修改后如何作用于視圖。這一節主要記錄initCo...
摘要:前言最近在學習計算屬性的源碼,發現和普通的響應式變量內部的實現還有一些不同,特地寫了這篇博客,記錄下自己學習的成果文中的源碼截圖只保留核心邏輯完整源碼地址可能需要了解一些響應式的原理版本計算屬性的概念一般的計算屬性值是一個函數,這個函數showImg(https://user-gold-cdn.xitu.io/2019/5/6/16a8b98f1361f6f6); 前言 最近在學習Vue計...
摘要:這里面還有一些問題對應的回調函數這就是執行上下文收集依賴同步異步更新所謂的同步更新是指當觀察的主體改變時立刻觸發更新。 我們在前面推導過程中實現了一個簡單版的watcher。這里面還有一些問題 class Watcher { constructors(component, getter, cb){ this.cb = cb // 對應的回調函數,callback...
摘要:前言上一遍文章介紹了模版渲染的實現,這篇文章將繼續介紹雙向綁定的實現官網如下,當。 前言 上一遍文章介紹了Vue模版渲染的實現(https://segmentfault.com/a/11...),這篇文章將繼續介紹雙向綁定的實現 demo 官網demo如下,當data。message的值變化,input的value值也會相應的變化;當用戶改變input框中的內容時data.messag...
閱讀 1271·2021-10-18 13:32
閱讀 2346·2021-09-24 09:47
閱讀 1331·2021-09-23 11:22
閱讀 2469·2019-08-30 14:06
閱讀 576·2019-08-30 12:48
閱讀 2004·2019-08-30 11:03
閱讀 542·2019-08-29 17:09
閱讀 2469·2019-08-29 14:10