vuejs源碼學習筆記一(看懂vue源碼)

  • 1、深入淺出Vue.js–變化偵測
  • 2、Vue學習系列一 —— MVVM響應式系統的基本實現原理
  • 3、.vue文件怎麼寫js代碼
  • 4、認識Vue.js+Vue.js的優缺點+和與其他前端框架的區別
  • 5、vue入門 | 使用vue.js2.0 + ElementUI開發後台管理系統詳細教程(一)
  • 6、如何學習vuejs

偵測狀態變化,重新渲染頁面。

拉(通知狀態改變,然後暴力比對哪些節點需要重新渲染): Angular臟檢查、React虛擬dom

推(明確知道哪些狀態改變,細粒度,通知綁定這個狀態的依賴節點更新): Vue

但,粒度越細,每個狀態綁定的依賴越多,追蹤開銷就越大。從Vue2.0開始引入虛擬dom,綁定依賴到組件層面,而不是節點層面。 狀態改變,通知到組件,組件內部再使用虛擬dom進行比對。

追蹤變化 Object.defineProperty 和 Proxy

收集依賴

當數據發生變化的時候,需要通知使用了該數據的地方。所以在gettter中收集依賴,在setter中觸發依賴。

為了減少耦合,封裝Dep類,專門管理依賴

收集的依賴window.target,到底是啥?依賴是用到數據的地方,可能是模板,可能是用戶寫的一個watch,需要抽象出一個類集中處理多種情況,收集依賴階段只收集這個類的實例,通知也只通知它,它再負責通知其他地方 — Watcher。

遞歸偵測所有key

封裝一個Observer類用於將data中的所有屬性(包括子屬性)都轉化成getter/setter的形式。

getter/setter只能追蹤一個屬性是否被修改,但無法追蹤新增和刪除屬性,所以另外提供了vm. delete兩個api。ES6之前。

偵測Object變化是通過getter/setter實現的,但是如果用Array原型上的方法改變數組,就無法偵測了。同setter追蹤,如果可以在用戶使用Array原型上的方法改變數組時,得到通知,就可以偵測變化。

我們可以用一個攔截器arrayMethods去覆蓋Array.prototype,在攔截器中發送變化通知, 再執行原本的功能。改變數組自身內容的7個方法: [‘push’, ‘pop’, ‘shift’, ‘unshift’, ‘splice’, ‘sort’, ‘reverse’]

攔截器arrayMethods不能直接覆蓋Array.prototype,會污染全局的Array。我們的攔截操作只需要針對那些被偵測了變化的數據生效,也就是說攔截器只覆蓋那些響應式數組的原型。將一個數據轉化成響應式,需要用到Observer。

ES6用Object.getPropertyOf和Object.setPropertyOf替代了 proto 。

每次訪問數組的值,就會觸發getter。所以Array在getter里收集依賴,在攔截器中觸發依賴。

依賴列表dep存儲在Observer中,因為getter和攔截器中都可以訪問到Observer實例。

getter中訪問:

攔截器中訪問:

這樣,就可以通過數組值的 ob 屬性訪問到Observer實例上的dep,調用改變數組內容的方法時,通知依賴。同時,收集依賴中的observe函數中通過 ob 來判斷,數據是否已經被Observer轉換成了響應式。

偵測數組中元素變化

偵測新增元素變化

可以新增數組元素的方法為:push、unshift 和splice,可以取出新增元素,使用observeArray方法使其變成響應式的。

Array的變化偵測是通過攔截原型上方法實現的,所以對直接給數組某一項賦值,或者通過設置length改變數組,是偵測不到的。所以可以用api或方法代替。

expOrFn: a.b.c or 函數

options: { deep, immediate }

用於觀察一個表達式或computed函數在Vue實例上的變化。回調函數調用時,會從參數得到newValue和oldValue。返回一個取消觀察函數,用來停止觸發回調。

deep: watch對象內部值的變化,都會觸發回調

immediate: 立即以表達式的當前值觸發回調

所有vm.$開頭的屬性,都是寫在Vue.prototype上的。

原理

teardown 首先需要先在Watcher中記錄自己被收錄進了哪些Dep中,當unwatch時,遍歷自己的記錄列表,從dep依賴列表中把自己刪除。

deep實現原理:除了要觸發當前這個被監聽數據的收集依賴之外,需要把其所有子值都觸發一遍收集依賴。當子數據發生變化時,可以通知當前Watcher。

在taget上設置一個屬性,如果target是響應式的,被創建的屬性也是響應式的,並觸發視圖更新。主要用來避免vue偵測不到新增加屬性的限制。

用於刪除target對象上的key屬性。如果對象是響應式的,需要確保刪除能觸發更新試圖。主要為了避免直接使用delete無法被偵測到變化的限制。

MVVM是Model-View-ViewModel的簡寫。它模式是MVC—MVP—MVVM的進化版。

Model負責用JavaScript對象表示,View負責UI界面顯示,兩者做到了最大限度的分離。

而把Model和View關聯起來的就是ViewModel。ViewModel負責把Model的數據同步到View顯示出來,還負責把View的界面修改同步回Model更新數據。

臟值檢查 : angular.js 是通過臟值檢測的方式來比對數據是否有變更而決定是否更新視圖。

原理是,拷貝一份 copy_viewModel 在內存中,用戶操作導致 viewModel 發生改變的行為時,框架都會把 copy_viewModel 和最新的 viewModel 進行深度比較,一旦發現有屬性發生變化,則重新渲染與之綁定的DOM節點。

最簡單的方式就是通過 setInterval() 定時輪詢檢測數據變動,angular觸發時進入臟值檢測。但只限 指定的事件 (如:用戶點擊,輸入操作,ajax請求,setInterval,setTimeout等…),否則需手動調用 apply 函數去強制執行一次臟檢查。

數據劫持 : vue.js 則是採用數據劫持結合發布者-訂閱者模式的方式,通過 Object.defineProperty() 來劫持各個屬性的 setter , getter 在數據變動時發布消息給訂閱者,觸發相應的監聽回調,而產生更新數據和視圖。

原理圖告訴我們,data屬性定義了getter、setter對屬性進行劫持,當屬性值改變是就會notify通知watch對象,而watch對象則會重新觸發組件呈現功能,繼而更新view上的DOM節點樹。

反之,view上輸入數據時,也會觸發data變更,也會觸發訂閱者watch更新,這樣子model數據就可以實時更新view上的數據變化。這樣一個過程就是vue的數據雙向綁定了。

vue是通過數據劫持的方式來做數據綁定的,其中最核心的方法便是通過 Object.defineProperty() 來實現對屬性的劫持,達到監聽數據變動的目的。

Object.defineProperty 是ES5一個方法,可以直接在一個對象上定義一個新屬性,或者修改一個已經存在的屬性,並返回這個對象,對象里目前存在的屬性描述符有兩種主要形式: 數據描述符 和 存取描述符 。

數據描述符 是一個擁有可寫或不可寫值的屬性。

存取描述符 是由一對getter-setter函數功能來描述的屬性。

描述符必須是兩種形式之一;不能同時是兩者。即:有值和可寫,或者可get和set

屬性描述符包括:

我們已經知道怎麼實現數據的雙向綁定,首先要對數據進行劫持監聽,所以我們需要設置一個監聽器 Observer ,用來監聽所有屬性。如果屬性發上變化了,就需要告訴訂閱者 Watcher 看是否需要更新。因為訂閱者是有很多個,所以我們需要有一個消息訂閱器 Dep 來專門收集這些訂閱者,然後在監聽器 Observer 和訂閱者 Watcher 之間進行統一管理的。接着,我們還需要有一個指令解析器 Compile ,對每個節點元素進行掃描和解析,將相關指令對應初始化成一個訂閱者 Watcher ,並替換模板數據或者綁定相應的函數,此時當訂閱者 Watcher 接收到相應屬性的變化,就會執行對應的更新函數,從而更新視圖。

因此接下去我們執行以下4個步驟,實現數據的雙向綁定:

深入響應式原理

剖析Vue原理實現雙向綁定MVVM

《響應式系統的基本原理》.js

JavaScript實現MVVM之我就是想監測一個普通對象的變化

單個組件裡面可以使用 import $ from ‘jquery’ 引用

當前你得使用npm把jquery 安裝了。 把jquery 用export default 導出來(就是在jquery.js的最後一行寫上 export default $), 然後使用import $ from ‘jquery的文件地址’

至於 script標籤裡面怎麼寫

import $ from ‘jquery’

export default {

  data: function() {

    return {

      testData: 1 // 這個對象裡面定義所有的變量 這些變量可以 在html直接和dom綁定

    }

  },

  mounted: function() {

    // 生命周期函數, 有好幾個 執行的順序都不一樣,可以根據場景 選擇不同的生命周期函數 這塊一般是初始化數據的地方

  },

  methods: { // 這裡寫所有的方法, 這些方法可以在 方法內部使用this.方法名調用,也可以在html 中使用@時間名 = ‘函數名()’調用

    init() {  

      // 實例方法

      // 使用this.變量可以訪問data中的變量

      console.log(this.testData)

    }

  }

}

首先,我們先了解什麼是MVX框架模式?

MVX框架模式:MVC+MVP+MVVM

1.MVC:Model(模型)+View(視圖)+controller(控制器),主要是基於分層的目的,讓彼此的職責分開。

View通過Controller來和Model聯繫,Controller是View和Model的協調者,View和Model不直接聯繫,基本聯繫都是單向的。

用戶User通過控制器Controller來操作模板Model從而達到視圖View的變化。

2.MVP:是從MVC模式演變而來的,都是通過Controller/Presenter負責邏輯的處理+Model提供數據+View負責顯示。

在MVP中,Presenter完全把View和Model進行了分離,主要的程序邏輯在Presenter里實現。

並且,Presenter和View是沒有直接關聯的,是通過定義好的接口進行交互,從而使得在變更View的時候可以保持Presenter不變。

MVP模式的框架:Riot,js。

3.MVVM:MVVM是把MVC里的Controller和MVP里的Presenter改成了ViewModel。Model+View+ViewModel。

View的變化會自動更新到ViewModel,ViewModel的變化也會自動同步到View上顯示。

這種自動同步是因為ViewModel中的屬性實現了Observer,當屬性變更時都能觸發對應的操作。

MVVM模式的框架有:AngularJS+Vue.js和Knockout+Ember.js後兩種知名度較低以及是早起的框架模式。

Vue.js是什麼?

看到了上面的框架模式介紹,我們可以知道它是屬於MVVM模式的框架。那它有哪些特性呢?

其實Vue.js不是一個框架,因為它只聚焦視圖層,是一個構建數據驅動的Web界面的庫。

Vue.js通過簡單的API(應用程序編程接口)提供高效的數據綁定和靈活的組件系統。

Vue.js的特性如下:

1.輕量級的框架

2.雙向數據綁定

3.指令

4.插件化

Vue.js與其他框架的區別?

1.與AngularJS的區別

相同點:

都支持指令:內置指令和自定義指令。

都支持過濾器:內置過濾器和自定義過濾器。

都支持雙向數據綁定。

都不支持低端瀏覽器。

不同點:

1.AngularJS的學習成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比較簡單、直觀。

2.在性能上,AngularJS依賴對數據做臟檢查,所以Watcher越多越慢。

Vue.js使用基於依賴追蹤的觀察並且使用異步隊列更新。所有的數據都是獨立觸發的。

對於龐大的應用來說,這個優化差異還是比較明顯的。

2.與React的區別

相同點:

React採用特殊的JSX語法,Vue.js在組件開發中也推崇編寫.vue特殊文件格式,對文件內容都有一些約定,兩者都需要編譯後使用。

中心思想相同:一切都是組件,組件實例之間可以嵌套。

都提供合理的鉤子函數,可以讓開發者定製化地去處理需求。

都不內置列數AJAX,Route等功能到核心包,而是以插件的方式加載。

在組件開發中都支持mixins的特性。

不同點:

React依賴Virtual DOM,而Vue.js使用的是DOM模板。React採用的Virtual DOM會對渲染出來的結果做臟檢查。

Vue.js在模板中提供了指令,過濾器等,可以非常方便,快捷地操作DOM。

如何使用Vue.js?

1.安裝

(1)script

如果項目直接通過script加載CDN文件,代碼示例如下:

script src=””/script

(2)npm

如果項目給予npm管理依賴,則可以使用npm來安裝Vue,執行如下命令:

$npm i vue –save-dev

(3)bower

如果項目基於bower管理依賴,則可以使用bower來安裝Vue,執行如下命令:

$bower i vue –save-dev

項目首頁由頂部導航欄,左側導航欄,中間內容區構成,如圖

在app.vue引入element-ui,然後就可以在其他任何頁面中使用了

將app.vue改為以下內容

最近VueJs確實火了一把,自從Vue2.0發布後,Vue就成了前端領域的熱門話題,github也突破了三萬的star,那麼對於新手來說,如何高效快速的學習Vue2.0呢。既然大家會看這篇文章,那麼肯定是vue的學習者了,或是遇到的瓶頸,或者剛剛開始學,不知道如何快速起步,本篇文章將帶領大家在最短的時間內構件一個學習Vue的學習路線Vuejs的作者尤雨溪尤大也寫過一篇關於新手學習vue路徑的文章新手向:Vue 2.0 的建議學習順序百度vuejs搜索的是vue1的文檔,推薦大家直接上2.0,畢竟1和2還是有區別的。vue2.0文檔地址Vue2.0Vue基礎對於沒有接觸過es6和webpack的童鞋來說,不建議直接用官方的腳手架vue-cli構件項目。先按文檔順序最少學習完組件那一章。直接在html文件中引入vue.js開始學習,了解vue的基礎指令和語法。vue的生命周期很重要,了解這點以後可以免去很多問題。學完這些可以做一些練手的小項目,比如萬年不變的todolist。。。現在可以開始學習使用vue-cli構件項目了,學習組件化之前,推薦先看一下es6關於模塊的介紹。阮一峰《ECMAScript6》 Module光會這些還是不夠的,還得會一些npm基礎,知道如何用git-bash來安裝依賴,會一些常用的命令。這方面的知識可以參閱npm入門文檔看完這些就可以試着將之前的寫的demo用搭建的vue-cli來實現。附上我寫的一個入門小demovue-demo-search多看看組件那裡,看看如何在vue-cli中怎麼實現組件化,說白了,vue玩的就是組件。到這裡vue基礎篇就結束了。你還可以有條件的參閱剩下的官方文檔裡面的進階篇,如果時間有限,就直接進入vue-router Vue-router和之前一樣,推薦直接用html+js過一遍文檔對路由導航鉤子得好好看一看。看完文檔就可以上手vue-cli,一般新手在這幾天都會死活跑不出來。偷笑最直接的方法就是去github上搜一些關於vue-router2.0的demo,看如何構件路由,如何構件項目目錄。我這裡有一個傳送門如果能跑出來,就可以做一些小項目了,比如寫一個知乎日報啊偷笑,這些demo在github上很多。可以結合一些組件庫寫demo,這樣可以更加了解組件化。比如餓了么團隊的Element、mint-ui Vuex什麼是vuex?Vuex 是一個專門為 Vue.js 應用設計的 狀態管理模型 + 庫。它為應用內的所有組件提供集中式存儲服務,其中的規則確保狀態只能按預期方式變更。說白了就是控制應用的一些全局狀態。狀態改變了,對應的視圖也會改變。在學習Vuex時,會有一些ES6特性,當遇到這些時,最好不要一帶而過,去好好看一看這些es6特性。比如在學習Action時可以看看ES6新增的Promise和參數解構。實踐的方法一樣是先看別人別人寫的代碼,比如官方的購物車實例的應用結構。把之前寫的demo優化一下,有些地方可以用用vuex。vuex主要是用來對不同組件間進行通信,它構建了一個Vue實例的全局數據與方法,這些數據與方法可以在該Vue實例的所有組件中getter與setter。

原創文章,作者:TNKE7,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/126286.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
TNKE7的頭像TNKE7
上一篇 2024-10-03 23:07
下一篇 2024-10-03 23:07

相關推薦

  • Python學習筆記:去除字符串最後一個字符的方法

    本文將從多個方面詳細闡述如何通過Python去除字符串最後一個字符,包括使用切片、pop()、刪除、替換等方法來實現。 一、字符串切片 在Python中,可以通過字符串切片的方式來…

    編程 2025-04-29
  • 雲智直聘 源碼分析

    本文將會對雲智直聘的源碼進行分析,包括前端頁面和後端代碼,幫助讀者了解其架構、技術實現以及對一些常見的問題進行解決。通過本文的閱讀,讀者將會了解到雲智直聘的特點、優勢以及不足之處,…

    編程 2025-04-29
  • Python網站源碼解析

    本文將從多個方面對Python網站源碼進行詳細解析,包括搭建網站、數據處理、安全性等內容。 一、搭建網站 Python是一種高級編程語言,適用於多種領域。它也可以用於搭建網站。最常…

    編程 2025-04-28
  • 源碼是什麼

    源碼是一段計算機程序的原始代碼,它是程序員所編寫的可讀性高、理解性強的文本。在計算機中,源碼是指編寫的程序代碼,這些代碼按照一定規則排列,被計算機識別並執行。 一、源碼的組成 源碼…

    編程 2025-04-27
  • Go源碼閱讀

    Go語言是Google推出的一門靜態類型、編譯型、並髮型、語法簡單的編程語言。它因具有簡潔高效,內置GC等優秀特性,被越來越多的開發者所鍾愛。在這篇文章中,我們將介紹如何從多個方面…

    編程 2025-04-27
  • Python怎麼看源碼

    本文將從以下幾個方面詳細介紹Python如何看源碼,幫助讀者更好地了解Python。 一、查看Python版本 在查看Python源碼之前,首先需要確認Python版本。可以在命令…

    編程 2025-04-27
  • 源碼審計面試題用法介紹

    在進行源碼審計面試時,可能會遇到各種類型的問題,本文將以實例為基礎,從多個方面對源碼審計面試題進行詳細闡述。 一、SQL注入 SQL注入是常見的一種攻擊方式,攻擊者通過在輸入的參數…

    編程 2025-04-27
  • 對3ue源碼的多方面闡述

    一、3ue源碼簡述 3ue是一款基於Vue.js開發的富文本編輯器,支持圖片上傳、粘貼、表格、代碼塊等多種功能,具有輕量、可定製、易擴展的特點。下面我們將從多個方面對3ue源碼進行…

    編程 2025-04-22
  • 全面解析ptable:從使用到源碼分析

    ptable是一個輕量級的DOM操作插件,主要用於表格的操作和功能增強。它的使用非常靈活,支持多種操作方式,包括添加、刪除、修改、排序、篩選等,可以大大提高表格的效率和易用性。 一…

    編程 2025-04-22
  • Kali-Linux學習筆記:如何切換root用戶

    一、為什麼需要切換root用戶 在Linux下,root是系統的超級管理員賬戶,具有最高的權限。默認情況下,普通用戶是無法執行一些系統性操作的,如修改系統配置文件等。所以,有時候我…

    編程 2025-04-18

發表回復

登錄後才能評論