自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

大概幾集下飯劇時(shí)間就能懂的Vue3原理

開發(fā) 前端
Vue3 組件組件(Component)是 Vue.js最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML元素,封裝可重用的代碼。這篇文章為你帶來(lái)一份VUE3原理速成指南。

[[420825]]

大概幾集下飯劇時(shí)間就能懂的VUE3原理

大家好,我是卡頌。

最近中午沒胃口,找來(lái)VUE源碼相關(guān)視頻來(lái)當(dāng)下飯劇。幾頓飯下去,人胖了,VUE也整明白了。

這篇文章為你帶來(lái)一份VUE3原理速成指南。

模塊劃分

如果我們用「VUE的模版語(yǔ)法」定義:

  1. <div>hello</div> 

最終VUE會(huì)幫我們?cè)跒g覽器中渲染對(duì)應(yīng)的DOM節(jié)點(diǎn)。

這之間對(duì)這段節(jié)點(diǎn)的描述會(huì)經(jīng)歷4次變化,橫跨「編譯時(shí)」與「運(yùn)行時(shí)」:

「模版語(yǔ)法」在編譯時(shí)會(huì)被「編譯器」轉(zhuǎn)化為「render函數(shù)」,類似:

  1. render(h) { 
  2.   return h('div''hello'); 

在運(yùn)行時(shí),「render函數(shù)」執(zhí)行后返回的「h函數(shù)的執(zhí)行結(jié)果」就是VNode(也就是虛擬DOM),類似:

  1.   tag: "div"
  2.   children: [ 
  3.     { 
  4.       text: "Hello" 
  5.     } 
  6.   ] 

最終,VUE根據(jù)VNode的信息,在瀏覽器渲染對(duì)應(yīng)DOM。

那么,是誰(shuí)在驅(qū)動(dòng)這一流程?

mount和patch

組件有兩種不同的渲染邏輯:「首次渲染」和「更新」。

「首次渲染」意味著從無(wú)到有,比如上文的VNode:

  1.   tag: "div"
  2.   children: [ 
  3.     { 
  4.       text: "Hello" 
  5.     } 
  6.   ] 

可能對(duì)應(yīng)如下DOM操作:

  1. const node = document.createElement(VNode.tag); 
  2. node.textConent = 'Hello'
  3. contanerDOM.appendChild(node); 

「更新」則需要對(duì)比更新前后VNode,對(duì)變化部分執(zhí)行DOM操作。

比如,以上VNode如果變?yōu)椋?/p>

  1.   tag: "div"
  2.   children: [ 
  3.     { 
  4.       // text改變 
  5.       text: "world" 
  6.     } 
  7.   ] 

則最終執(zhí)行:

  1. node.textContent = 'world'

VUE的「首次渲染」對(duì)應(yīng)mount模塊,「更新」對(duì)應(yīng)patch模塊。

所以,render函數(shù)執(zhí)行后返回VNode,根據(jù)情況不同,會(huì)走mount或patch的渲染邏輯:

如果想深入虛擬DOM相關(guān)知識(shí),推薦閱讀snabbdom[1]源碼。這是個(gè)優(yōu)秀的虛擬DOM庫(kù),VUE2的虛擬DOM部分就是fork這個(gè)庫(kù)改造的。

那么是誰(shuí)在什么時(shí)機(jī)調(diào)用了render函數(shù)呢?

響應(yīng)式更新

在VUE中,狀態(tài)變化會(huì)實(shí)時(shí)反映到視圖上,比如:

  1. <div @click="count++">{{count}}</div> 

點(diǎn)擊div后:

  1. 觸發(fā)點(diǎn)擊事件,count變化
  2. count變化觸發(fā)回調(diào),回調(diào)中更新視圖

當(dāng)前我們已經(jīng)知道第二步是由于觸發(fā)了如下流程:

所以只需要建立count變化到執(zhí)行render函數(shù)的聯(lián)系即可。

具體來(lái)說(shuō),我們希望實(shí)現(xiàn)reactive及watchEffect:

  1. // 定義狀態(tài) 
  2. const state = reactive({count: 0}); 
  3.  
  4. // 監(jiān)聽狀態(tài)變化 
  5. watchEffect(() => { 
  6.   console.log(state.count); 
  7. }) 
  8.  
  9. // 改變狀態(tài) 
  10. state.count++; 

reactive定義狀態(tài)。

watchEffect根據(jù)回調(diào)執(zhí)行的情況決定監(jiān)聽哪些狀態(tài)。

比如watchEffect回調(diào)執(zhí)行了console.log(state.count);,他就會(huì)監(jiān)聽state的變化。

當(dāng)執(zhí)行state.count++;,由于watchEffect監(jiān)聽了state的變化,則其回調(diào)會(huì)觸發(fā),打印state.count。

這就是Reactivity模塊。

VUE官方推出了VUE3響應(yīng)式原理[2]課程講解Reactivity的實(shí)現(xiàn),這是B站鏈接。如果經(jīng)濟(jì)允許,請(qǐng)支持正版[3]

當(dāng)實(shí)現(xiàn)了Reactivity模塊,我們就能將「組件狀態(tài)」與后續(xù)流程串聯(lián)起來(lái)。

剛才講過(guò),render函數(shù)是編譯器根據(jù)「模版語(yǔ)法」生成的。在面對(duì)帶狀態(tài)的模版語(yǔ)法時(shí),比如上文的count:

  1. <div @click="count++">{{count}}</div> 

render函數(shù)內(nèi)的count是響應(yīng)式的(即:count實(shí)際是reactive({count: 0}))。

那么就能用watchEffect監(jiān)聽count的變化。

所以,在應(yīng)用初始化時(shí),會(huì)有類似邏輯:

  1. let isMounted = false
  2. let oldVNode; 
  3. watchEffect(() => { 
  4.   if (!isMounted) { 
  5.     // mount邏輯 
  6.     // 調(diào)用render函數(shù) 
  7.     oldVNode = component.render(); 
  8.     // mount 
  9.     mount(oldVNode); 
  10.   } else { 
  11.     // patch邏輯 
  12.     // 調(diào)用render函數(shù) 
  13.     newVNode = component.render(); 
  14.     patch(oldVNode, newVNode); 
  15.     oldVNode = newVNode; 
  16.   } 
  17. }) 

其中component.render()(render函數(shù)的執(zhí)行)達(dá)到上文「監(jiān)聽狀態(tài)變化」的效果:

  1. // 監(jiān)聽狀態(tài)變化 
  2. watchEffect(() => { 
  3.   console.log(state.count); 
  4. }) 

所以,該組件內(nèi)任何狀態(tài)變化都會(huì)觸發(fā)watchEffect的執(zhí)行,watchEffect回調(diào)內(nèi)會(huì)觸發(fā)后續(xù)流程。

總結(jié)

VUE3按原理大體可以劃分為:

  • mount
  • patch
  • 編譯器
  • Reactivity

VUE官方推出了實(shí)現(xiàn)簡(jiǎn)易VUE3教程[4],感興趣的朋友可以去看看。如果有能力,記得去支持正版[5]哦。

參考資料

[1]snabbdom:

https://github.com/snabbdom/snabbdom

[2]VUE3響應(yīng)式原理:

https://www.bilibili.com/video/BV1SZ4y1x7a9/?spm_id_from=333.788.b_7265636f5f6c697374.6

[3]正版:

https://www.vuemastery.com/free-weekend/?gclid=Cj0KCQjwpreJBhDvARIsAF1_BU16x7gElbhGqGzZZ1geo5RzOqz_PuaJzBM41jHcAAC6CPwPSPvo8G8aAkdhEALw_wcB

[4]實(shí)現(xiàn)簡(jiǎn)易VUE3教程:

https://www.bilibili.com/video/BV1rC4y187Vw?p=10

[5]正版:

https://www.vuemastery.com/free-weekend/?gclid=Cj0KCQjwpreJBhDvARIsAF1_BU16x7gElbhGqGzZZ1geo5RzOqz_PuaJzBM41jHcAAC6CPwPSPvo8G8aAkdhEALw_wcB

 

責(zé)任編輯:姜華 來(lái)源: 魔術(shù)師卡頌
相關(guān)推薦

2020-12-01 08:34:31

Vue3組件實(shí)踐

2021-12-01 08:11:44

Vue3 插件Vue應(yīng)用

2021-11-30 08:19:43

Vue3 插件Vue應(yīng)用

2023-11-28 09:03:59

Vue.jsJavaScript

2021-09-27 06:29:47

Vue3 響應(yīng)式原理Vue應(yīng)用

2021-12-02 05:50:35

Vue3 插件Vue應(yīng)用

2020-09-19 21:15:26

Composition

2022-08-15 12:31:32

Vue3TypeScript

2019-06-10 08:04:26

分布式鎖JVM服務(wù)器

2021-12-08 09:09:33

Vue 3 Computed Vue2

2020-11-12 08:32:14

Vue3模板優(yōu)化

2022-06-21 12:09:18

Vue差異

2021-05-26 10:40:28

Vue3TypeScript前端

2021-11-16 08:50:29

Vue3 插件Vue應(yīng)用

2022-03-10 11:04:04

Vue3Canvas前端

2024-11-06 10:16:22

2024-12-03 10:40:51

Vue3injectprovide

2024-09-05 08:50:11

2021-11-26 05:59:31

Vue3 插件Vue應(yīng)用

2021-12-29 07:51:21

Vue3 插件Vue應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)