欧美亚洲综合图区在线|天天射天天干国产成卜|99久久免费国产精精品|国产的欧美一区二区三区|日韩中文字幕无码不卡专区|亚麻成人aV极品一区二区|国产成人AV区一区二区三|成人免费一区二区三区视频网站

當(dāng)前位置:首頁 > 軟件開放 > 正文內(nèi)容

vue2響應(yīng)式原理源碼(vue20響應(yīng)式原理)

軟件開放2年前 (2023-04-09)1404

本篇文章給大家談?wù)剉ue2響應(yīng)式原理源碼,以及vue20響應(yīng)式原理對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。

本文目錄一覽:

vue.js響應(yīng)式原理

vue2響應(yīng)式原理主要通過 Object.fefineProperty

當(dāng)把一個(gè)普通的js對象傳入 Vue 實(shí)例作為 data 選項(xiàng),Vue將遍歷此對象所有的屬性,并使用 Object.fefineProperty 把這些屬性全部轉(zhuǎn)為 getter/setter 。 Object.defineProperty 是ES5中一個(gè)無法 shim 的特性,這也是Vue 不支持IE8 以及更低版本瀏覽器的原因。

vue3響應(yīng)式原理主要通過 Proxy 代理對象

虛擬dom就是用普通的js對象來描述 DOM 對象

真實(shí)dom成員復(fù)雜,虛擬dom可以用簡潔的方式來表示實(shí)現(xiàn)真實(shí)dom,創(chuàng)建虛擬dom開銷小。

虛擬dom庫

使用模塊

Snabbdom 核心

patch 整體過程分析

vue數(shù)組響應(yīng)式原理

vue2中Object.defineProperty響應(yīng)式只對對象有效,對數(shù)組無效,所以對數(shù)組做額外處理。我們知道,會改變數(shù)組本身的方法只有7個(gè):sort, push, pop, slice, splice, shift, unshift,所以可以通過重寫這些方法來達(dá)到數(shù)組響應(yīng)式

解決方案:

1. 找到數(shù)組原型

2. 覆蓋那些能夠修改數(shù)組的更新方法,讓他們在修改數(shù)組同時(shí),還可以通知更新

3. 將得到的新的原型設(shè)置到數(shù)組實(shí)例原型上

4. 對數(shù)組內(nèi)部元素實(shí)現(xiàn)響應(yīng)式

// 實(shí)現(xiàn)數(shù)組響應(yīng)式// 1. 替換數(shù)組原型中7個(gè)方法constoriginalProto=Array.prototype// 克隆體原數(shù)組原型constarrayProto=Object.create(originalProto)// 可修改數(shù)組的7個(gè)方法 , 'sort'constchangeMethods=['push','pop','shift','unshift','slice','splice','sort']//? 2. 在克隆的原型上,覆蓋那些能夠修改數(shù)組的更新方法,讓他們在修改數(shù)組同時(shí),還可以通知更新changeMethods.forEach(method={arrayProto[method]=function(){// 進(jìn)行原始操作originalProto[method].apply(this,arguments)// 覆蓋操作:增加更新通知console.log(`數(shù)組正在執(zhí)行${method}方法`);}})// 對象響應(yīng)化functiondefineReactive(obj,key,value){Object.defineProperty(obj,key,{get(){console.log('獲取'+key);returnvalue},set(newVal){if(newVal!==value){// console.log(newVal);// console.log(JSON.stringify(obj[key]));console.log(`正在改變${key}值:從${obj[key]}變?yōu)?{newVal}`)value=newVal}}})}functionobserver(obj){// 不是對象或者為null,不做響應(yīng)式,結(jié)束if(typeofobj!=='object'||obj===null)return;// 如果是數(shù)組,修改其實(shí)例的原型if(Array.isArray(obj)){// 3. 將得到的新的原型設(shè)置到數(shù)組實(shí)例原型上obj.__proto__=arrayProto// 4. 對數(shù)組內(nèi)的元素,同樣進(jìn)行響應(yīng)化for(leti=0;iobj.length;i++){// console.log(obj[i]);observer(obj[i])}// 如果是對象}else{Object.keys(obj).forEach(key={console.log(obj,key,obj[key]);defineReactive(obj,key,obj[key])})}}obj=[{a:1},2,7,5,3]observer(obj)obj.push(4)// 數(shù)組正在執(zhí)行push方法obj.pop()// 數(shù)組正在執(zhí)行pop方法obj[0].a=2// 獲取a? ? // 正在改變a值:從1變?yōu)?obj.sort()// 數(shù)組正在執(zhí)行sort方法console.log(obj);// [ 2, 3, 5, 7, { a: [Getter/Setter] } ]console.log(obj[4].a);// 獲取a? // 2

鏈接:

vue2數(shù)據(jù)響應(yīng)式原理

vue2響應(yīng)式原理由 Observer 類, Dep 類和 Watcher 類互相調(diào)用實(shí)現(xiàn), Observer 類是把一個(gè)普通的object類變成每一層都能相應(yīng)的類, Dep 類的作用是添加,移除,通知和收集訂閱者, Watcher 類是訂閱者,主要功能是把當(dāng)數(shù)據(jù)改變的時(shí)候,去調(diào)用回調(diào)函數(shù),修改dom節(jié)點(diǎn)

那么是怎么實(shí)現(xiàn)響應(yīng)式的呢,首先是一個(gè)函數(shù),要先轉(zhuǎn)換為可響應(yīng)的,那就需要用到 Observer 類

這個(gè) observe 函數(shù)就是對 Observer 類做多了一層封裝

而 Observer 類是通過 Object.defineProperty 來監(jiān)控?cái)?shù)據(jù)的獲取和改變的

關(guān)鍵在于 defineReactive 方法,這個(gè)方法是對 Object.defineProperty 做了一層封裝,并且對對象的每一層做遞歸調(diào)用,實(shí)現(xiàn)了每一層都有響應(yīng)監(jiān)控

但是是怎么知道現(xiàn)在要保存哪一個(gè) Watcher 實(shí)例到訂閱者數(shù)組里面的呢?其實(shí)就是用了這個(gè) Dep.target , Dep.target 相當(dāng)于 window.target ,全局只有一個(gè),全局也能訪問

首先得先講一講 Watcher 類,我們先回到上面的index.js,對象要讓 Watcher 類進(jìn)行監(jiān)聽,而 Watcher 有3個(gè)參數(shù),第一個(gè)是監(jiān)聽的對象,第二個(gè)是監(jiān)聽的屬性,比如 a.b.c.d ,第三個(gè)是屬性改變后觸發(fā)的回調(diào)函數(shù)

先來講一下 parsePath ,這個(gè)在工具類里,作用是訪問 a.b.c.d 這種鏈?zhǔn)綄傩?/p>

首先是觸發(fā)了 Watcher 的 get() 方法,把當(dāng)前實(shí)例保存在了 Dep.target 里面

然后在調(diào)用 parsePath 獲取屬性值的過程中,會挨個(gè)訪問響應(yīng)對象的屬性,就會觸發(fā)相應(yīng)的 getter ,我們回到 defineReactive.js ,可以發(fā)現(xiàn)這時(shí)候相應(yīng)屬性的 getter 就會把 Dep.target 也就是相應(yīng)的 Watcher 的實(shí)例保存在了 Dep 類的訂閱者數(shù)組里面

最后,在改變屬性的時(shí)候,相應(yīng)屬性的 setter 就會通知之前已經(jīng)保存的訂閱者數(shù)組,遍歷觸發(fā)回調(diào)

vue2響應(yīng)式原理總結(jié)

vue組件實(shí)例化時(shí),會對data屬性深度遍歷(遇到數(shù)組或者對象)為每一個(gè)屬性添加數(shù)據(jù)劫持。數(shù)據(jù)劫持就是使用Object.defineProperty(de fai in pro pu tei)方法添加get/set方法。

在這個(gè)過程中會實(shí)例化一個(gè)Dep類。

1.在get攔截器里觸發(fā)dep實(shí)例的depend方法,進(jìn)行依賴收集,實(shí)質(zhì)是在dep的實(shí)例屬性sub數(shù)組中添加依賴這個(gè)屬性的watcher實(shí)例。

2.在set攔截器里觸發(fā)dep實(shí)例的notify方法,對收集到的所有依賴派發(fā)更新,(watcher的update方法)

vue組件實(shí)例化時(shí)會實(shí)例化一個(gè)渲染watcher,渲染watcher實(shí)例化過程會做兩件事情。

1.創(chuàng)建vnode,在這個(gè)過程中,訪問了data屬性,觸發(fā)了get方法,完成了依賴收集。

2.觸發(fā)了子組件的實(shí)例化,子組件實(shí)例化又會重復(fù)上述數(shù)據(jù)劫持的過程。

這個(gè)過程就是對組件樹的深度遍歷。

結(jié)合組件生命周期來看整個(gè)過程,父組件會先觸發(fā)created鉤子,子組件后觸發(fā)created鉤子。而子組件mouted鉤子會先執(zhí)行,父組件的mouted鉤子后執(zhí)行。

分步驟記憶

1、實(shí)現(xiàn)頁面不刷新的原理

2、頁面視圖刷新的原理

實(shí)現(xiàn)頁面不刷新

1.hash

2.history

3.abstract:支持所有 JavaScript 運(yùn)行環(huán)境,如 Node.js 服務(wù)器端。如果發(fā)現(xiàn)沒有瀏覽器的 API,路由會自動強(qiáng)制進(jìn)入這個(gè)模式。

1.hash(哈希模式),#符號后邊是瀏覽器行為,在改變的時(shí)候不對頁面進(jìn)行刷新(重新請求URL)(監(jiān)聽hashChange事件)

2.history模式,H5新增了pushState,replaceState連個(gè)新API,可以修改歷史記錄卻不會使瀏覽器刷新頁面。

視圖更新原理

其原理就是vue的響應(yīng)式更新dom的原理,m = v

m是數(shù)據(jù),也就是在vue-router install時(shí)在根組件(root vue component)添加了_route屬性,在匹配到對應(yīng)路由后更新了_route屬性值,繼而觸發(fā)了該屬性值的渲染watcher,在繼而觸發(fā)dom更新。

兩種模式的不同

1.部署時(shí),history模式需要服務(wù)端處理所有可能的路徑(例如配置nginx的配置文件),防止出現(xiàn)404。哈希模式則不需要。

2.URL表示不同。

v-model指令就是 v-bind:value 和 @input 的語法糖。

它即可以支持原生表單元素,也可以支持自定義組件

在自定義組件中其實(shí)際是這樣的:

它的實(shí)現(xiàn)通過自定義render函數(shù), 緩存了 vnode

Vue 在更新 DOM 時(shí)是異步執(zhí)行的,只要偵聽到數(shù)據(jù)變化,Vue 將開啟一個(gè)隊(duì)列,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)變更。

如果同一個(gè) watcher 被多次觸發(fā),只會被推入到隊(duì)列中一次。在緩沖時(shí)會去除重復(fù)數(shù)據(jù)避免不必要的計(jì)算和 DOM 操作。

$nextTick(cb) 目的是在DOM 更新完成后傳入的回調(diào)函數(shù)再被調(diào)用。

vue2中computed原理

要理解這個(gè),首先要理解vue2的數(shù)據(jù)響應(yīng)式原理,因?yàn)閏omputed這個(gè)API的實(shí)現(xiàn)是建立在數(shù)據(jù)響應(yīng)式的基礎(chǔ)之上的。

這里附上vue響應(yīng)式原理的地址: vue2數(shù)據(jù)響應(yīng)式原理

在vue的watcher實(shí)例中配置了lazy,dirty,value屬性,就是用來配合實(shí)現(xiàn)computed的API。vue在初始化computed時(shí),會給每一個(gè)computed屬性配置一個(gè)watcher,并配置lazy的值為true。在new Watcher時(shí),還會設(shè)置dirty為true。由于lazy為true,這個(gè)時(shí)候并不會執(zhí)行computed配置的get方法,也就是說不會去計(jì)算出這個(gè)計(jì)算屬性的值出來,那么什么時(shí)候才計(jì)算呢?就是在執(zhí)行render函數(shù)時(shí),會去取計(jì)算屬性的值,這個(gè)時(shí)候,會執(zhí)行計(jì)算屬性的getter。在getter里面,會先判斷dirty的值(為true,則表示當(dāng)前計(jì)算屬性的值為臟值,已經(jīng)過期了,需要重新計(jì)算出來;為false則表示當(dāng)前的值是最新的,不需要重新計(jì)算,直接取緩存里面的值就行了,也就是value字段的值)。如果為true,則調(diào)用watcher.evaluate方法計(jì)算最新的值出來,然后將dirty設(shè)為false,把最新的值賦值給value。在計(jì)算最新的值時(shí),也就是執(zhí)行我們在computed對象中配置的相應(yīng)的get函數(shù)。根據(jù)之前講的響應(yīng)式原理,會先將當(dāng)前的watcher掛到dep的靜態(tài)屬性target上,然后執(zhí)行g(shù)et,在這個(gè)過程中,會使用到data中的屬性,然后進(jìn)行依賴收集,將computed的watcher存到data數(shù)據(jù)對應(yīng)的dep中去。完了之后,將watcher從targetStack中彈出,這是dep的靜態(tài)屬性target的值又變成了render函數(shù)的watcher。以上步驟執(zhí)行完后,會判斷當(dāng)前dep的target是否還有值,有的話,會執(zhí)行watcher.depend()。這一步是為了讓依賴的data對應(yīng)的dep中不僅是收集到computed的wathcer,還要收集render函數(shù)的watcher,因?yàn)楫?dāng)我們依賴的data改變時(shí),不僅要通知到computed的watcher,還要通知render函數(shù)的watcher,達(dá)到重渲染的目的。然后會把最新的value值返回,這時(shí),render函數(shù)里面終于拿到了計(jì)算屬性的最新值了。假如后面繼續(xù)用到了這個(gè)計(jì)算屬性,那么在執(zhí)行計(jì)算屬性的getter時(shí),跟之前一樣,會先判斷dirty值,這個(gè)時(shí)候,dirty的值為false,則直接返回value值,也就是之前說的取緩存的值,不會再次運(yùn)行一遍計(jì)算屬性的get函數(shù)了。

當(dāng)某個(gè)時(shí)候,計(jì)算屬性依賴的data數(shù)據(jù)變了,則會先后觸發(fā)computed的watcher,還有render函數(shù)的watcher。在將vue的數(shù)據(jù)響應(yīng)式原理時(shí),我們知道,數(shù)據(jù)改變時(shí),是會觸發(fā)watcher的update方法。在這個(gè)方法里面,首先判斷l(xiāng)azy是否為true,這就是針對計(jì)算屬性設(shè)計(jì)的。我們可以看看源碼片段:

如果為true,則只做了一件非常簡單的事,就是把dirty設(shè)為了true,然后就沒了。這個(gè)時(shí)候會去執(zhí)行render函數(shù)的watcher.update。也就是把render函數(shù)的執(zhí)行交給了nextTick去管理,這也是之前講過的。在執(zhí)行render函數(shù)時(shí),又使用到了這個(gè)計(jì)算屬性,那么,則會執(zhí)行這個(gè)計(jì)算屬性的getter,判斷dirty是否為true,由于剛剛在執(zhí)行computed的wathcer.update時(shí),把dirty設(shè)為了true,這個(gè)時(shí)候肯定會執(zhí)行watcher.evaluate重新去計(jì)算最新的值,也就是執(zhí)行我們配置在computed里面的get函數(shù)。接下來的其實(shí)跟前面所講的都是一樣的了。

這里附上關(guān)于computed初始化的源碼片段:

以上就是個(gè)人對于computed原理的理解了。

【手把手教你搓Vue響應(yīng)式原理】(一)初識Vue響應(yīng)式

在講這個(gè)之前,首先要明白一點(diǎn),這個(gè)所謂的響應(yīng)式,其實(shí)本身就是對 MVVM 的理解。

MVVM 其實(shí)就是所謂的 Modal View ViewModal 。

簡單理解,就是你的 data 中的數(shù)據(jù),和 template 模板中的界面,本身就是兩個(gè)東西。

但是, Vue 給你做了一層中間的 ViewModal ,讓視圖上的改變能反映到 data 中, data 中的改變能反映到視圖上。

在這個(gè)反映過程中,ViewModal就是視圖和數(shù)據(jù)的一個(gè)橋梁。

同樣是讓 a + 1 。

在 Vue 中,這個(gè)橋梁是你看不見的,因?yàn)? Vue 都幫你完成了視圖和數(shù)據(jù)的變化傳遞。

而 React 就是侵入式的,因?yàn)橐@式地聲明 setState ,通過它,來設(shè)置變量的同時(shí),設(shè)置視圖的改變。

所以,所謂的侵入式,其實(shí)就是對于橋梁的侵入。

所以, Vue 的神奇之處就在于,不需要我們手動地顯示調(diào)用 setState ,也就是這個(gè)橋梁, Vue 已經(jīng)幫我們橋接上了。

要讓 data 改變的同時(shí),視圖也發(fā)生改變,所以,問題的所在,就是我們需要監(jiān)聽,什么時(shí)候,這個(gè)變量發(fā)生了變量。

然而, ES5 中,就有那么一個(gè)特性,可以做到對于數(shù)據(jù)的劫持(監(jiān)聽)。

它就是 Object.defineProperty 。

Object.defineProperty( obj, prop, descriptor ) 方法會直接在一個(gè)對象上定義一個(gè)新屬性,或者修改一個(gè)對象的現(xiàn)有屬性,并返回此對象,與此同時(shí),它可以對 對象的一些額外底層的屬性進(jìn)行設(shè)置 。例如可以設(shè)置 writable , enumerable , configurable 等屬性。

后面的額外屬性設(shè)置,才是我們使用它的重點(diǎn)。

但是,我們使用的不是上面的幾個(gè)屬性,最主要的還是它的 get set ,可以對屬性值的獲取和設(shè)置操作進(jìn)行攔截。

get主要是可以對值的獲取進(jìn)行攔截,,它必須要傳入一個(gè) return ,并且, 該函數(shù)的返回值會被用作屬性的值 。我們可以來看一個(gè)例子:

由于設(shè)置了 get ,所以,輸出 a.name 的時(shí)候直接會被攔截,走 get() 中的 return 所以,此時(shí), a.name 的值應(yīng)該是 你已經(jīng)被攔截了!。

set主要是可以對值的設(shè)置進(jìn)行攔截,該方法會接受一個(gè)參數(shù),那就是 被賦予的新值 。我們可以來看一個(gè)例子:

由于設(shè)置了 set ,所以,設(shè)置值的時(shí)候會被攔截,走 set() 中的方法。

所以, Vue 能自動獲取data中的改變,反映到視圖的原因,就是有對于變量的獲取和設(shè)置的劫持,當(dāng)變量發(fā)生改變的同時(shí), Vue 能在第一時(shí)間知道,并且對視圖做出相應(yīng)的改變操作。

而這把鑰匙就是 Object.defineProperty 。

【尚硅谷】Vue源碼解析之?dāng)?shù)據(jù)響應(yīng)式原理

Object.defineProperty() - MDN

vue2響應(yīng)式原理源碼的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于vue20響應(yīng)式原理、vue2響應(yīng)式原理源碼的信息別忘了在本站進(jìn)行查找喔。

掃描二維碼推送至手機(jī)訪問。

版權(quán)聲明:本文由飛速云SEO網(wǎng)絡(luò)優(yōu)化推廣發(fā)布,如需轉(zhuǎn)載請注明出處。

本文鏈接:http://landcheck.net/post/16021.html

“vue2響應(yīng)式原理源碼(vue20響應(yīng)式原理)” 的相關(guān)文章

蘋果手機(jī)軟件開發(fā)(蘋果手機(jī)軟件開發(fā)教程)

蘋果手機(jī)軟件開發(fā)(蘋果手機(jī)軟件開發(fā)教程)

今天給各位分享蘋果手機(jī)軟件開發(fā)的知識,其中也會對蘋果手機(jī)軟件開發(fā)教程進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、開發(fā)蘋果app需掌握什么開發(fā)工具? 2、在蘋果手機(jī)開發(fā)一款app軟件大概需要多少錢 3、ios端的手機(jī)app開發(fā)要怎么做? 4、開...

軟件開發(fā)機(jī)構(gòu)(軟件開發(fā)機(jī)構(gòu)有哪些)

軟件開發(fā)機(jī)構(gòu)(軟件開發(fā)機(jī)構(gòu)有哪些)

本篇文章給大家談?wù)勡浖_發(fā)機(jī)構(gòu),以及軟件開發(fā)機(jī)構(gòu)有哪些對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、全國排名前十的軟件開發(fā)培訓(xùn)機(jī)構(gòu)有哪些? 2、國內(nèi)最好的軟件開發(fā)培訓(xùn)機(jī)構(gòu)有哪些? 3、軟件開發(fā)公司有哪些? 4、軟件開發(fā)培訓(xùn)機(jī)構(gòu)有哪些??? 全國排名前十的軟...

蘇州軟件開發(fā)兼職(蘇州軟件招聘)

蘇州軟件開發(fā)兼職(蘇州軟件招聘)

今天給各位分享蘇州軟件開發(fā)兼職的知識,其中也會對蘇州軟件招聘進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、蘇州有什么靠譜勞務(wù)? 2、蘇州肯德基兼職工資待遇? 3、蘇州兼職 4、蘇州找工作,找兼職去哪里? 5、蘇州園區(qū)有什么工資可日結(jié)的兼職工...

sony相機(jī)官方售后電話(sony相機(jī)客服電話)

sony相機(jī)官方售后電話(sony相機(jī)客服電話)

今天給各位分享sony相機(jī)官方售后電話的知識,其中也會對sony相機(jī)客服電話進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、索尼相機(jī)合肥售后服務(wù)在哪里 2、哈爾濱的索尼相機(jī)售后服務(wù)在哪 3、襄陽SONY相機(jī)的售后服務(wù)電話是多少?地址在哪? 索尼相機(jī)...

網(wǎng)頁源碼獲取什么意思(網(wǎng)站源碼是什么東西)

網(wǎng)頁源碼獲取什么意思(網(wǎng)站源碼是什么東西)

本篇文章給大家談?wù)劸W(wǎng)頁源碼獲取什么意思,以及網(wǎng)站源碼是什么東西對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、網(wǎng)頁里源碼是什么 2、什么是網(wǎng)頁源代碼? 3、網(wǎng)頁制作源代碼是什么意思? 4、網(wǎng)頁源代碼指什么 5、網(wǎng)站的源代碼是什么意思? 6、網(wǎng)頁源代碼是...

cctv5手機(jī)在線直播觀看高清回放(cctv5在線直播觀看高清手機(jī)版)

cctv5手機(jī)在線直播觀看高清回放(cctv5在線直播觀看高清手機(jī)版)

本篇文章給大家談?wù)刢ctv5手機(jī)在線直播觀看高清回放,以及cctv5在線直播觀看高清手機(jī)版對應(yīng)的知識點(diǎn),希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、cctv5+手機(jī)在線直播觀看。為什么會出現(xiàn)排 2、直播CCTV5可以在哪回看? 3、手機(jī)可以看cctv5嗎 4、cctv5...

湖北省| 思茅市| 六枝特区| 明水县| 金昌市| 江山市| 建瓯市| 佛冈县| 清水县| 庄河市| 安宁市| 武宁县| 昌黎县| 台安县| 长顺县| 建湖县| 和田县| 岳阳县| 象山县| 崇仁县| 静海县| 上杭县| 都匀市| 梁山县| 黔西| 抚顺市| 唐海县| 维西| 台湾省| 米林县| 宝兴县| 宝兴县| 乌拉特中旗| 阳原县| 泰兴市| 资中县| 门源| 昆山市| 赫章县| 藁城市| 托克逊县|