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

Vue.js設(shè)計與實(shí)現(xiàn)之權(quán)衡的藝術(shù)

開發(fā) 前端
Vue.js框架就是結(jié)合兩者的優(yōu)點(diǎn),對命令式代碼進(jìn)行了封裝,對使用者提供可維護(hù)性更高的聲明式代碼。

1.寫在前面

本文便帶領(lǐng)大家進(jìn)入《Vue.js設(shè)計與實(shí)現(xiàn)》描述的宇宙,開啟探索框架設(shè)計的思想的旅程。

2.框架設(shè)計里到處都體現(xiàn)了權(quán)衡的藝術(shù)

作者在文章中寫到『框架設(shè)計里到處都體現(xiàn)了權(quán)衡的藝術(shù)』,的確在進(jìn)行設(shè)計模式和技術(shù)選型的時候,我們都會去綜合考慮性能和開發(fā)效率,去權(quán)衡各方面因素從而得到盡可能完善的框架。

框架是由各個模塊組成的,彼此關(guān)聯(lián)又相互獨(dú)立,要做到實(shí)現(xiàn)當(dāng)前的功能,又要考慮到后續(xù)的模塊拆分和拓展。作為框架的設(shè)計者,需要站在全局的角度去思考和設(shè)計,需要對整體的設(shè)計思路有著清晰的掌控。實(shí)現(xiàn)細(xì)節(jié)是在設(shè)計的時候不用太過于在意的視點(diǎn),不要囿于高山的霧層,畢竟它只是整個框架的冰山一角。

在Vue框架的設(shè)計中,最能體現(xiàn)這種權(quán)衡思想的可能是『命令式和聲明式』、『編譯時和運(yùn)行時』等之間的權(quán)衡,需要了解彼此的差異、汲取兩者的優(yōu)點(diǎn)。

3.命令式和聲明式

正如你所知道的,在計算機(jī)編程范式中有三種:命令式編程,聲明式編程和函數(shù)式編程。

命令式編程:是關(guān)注計算機(jī)執(zhí)行的步驟,即一步一步告訴計算機(jī)先做什么再做什么。

聲明式編程:以數(shù)據(jù)結(jié)構(gòu)的形式來表達(dá)程序執(zhí)行的邏輯。它的主要思想是告訴計算機(jī)應(yīng)該做什么,但不指定具體要怎么做。

函數(shù)式編程:是與聲明式編程關(guān)聯(lián)的,只關(guān)注做什么而不是怎么做。但函數(shù)式編程不僅僅局限于聲明式編程。

命令式

對于前端開發(fā)從業(yè)者而言,JQuery框架并不會陌生,它其實(shí)就是最經(jīng)典的命令式的框架設(shè)計,它關(guān)注計算機(jī)執(zhí)行的步驟,即關(guān)注過程。命令式編程其實(shí)就是寫給計算機(jī)看的,讓我們的自然語言能與代碼進(jìn)行一一對應(yīng),更符合我們做事邏輯。

$("#app")//獲取id為app的標(biāo)簽元素
.text("hello pingping")//設(shè)置標(biāo)簽的文本內(nèi)容
.on("click",()=>console.log("hello onechuan"));//給id為app的便簽綁定事件

等價于原生js的代碼:

const div = document.querySelector("#app");
div.innerText = "hello pingping";
div.addEventListener("click",()=>console.log("hello onechuan"))

聲明式

而聲明式更關(guān)注實(shí)現(xiàn)結(jié)果,具體的實(shí)現(xiàn)過程并不是使用者所在意的,這也很大程度地降低了認(rèn)知成本,關(guān)注表層邏輯提升使用效率。

事實(shí)上,Vue.js的設(shè)計并不是簡單使用純粹的命令式或是聲明式編程,而是結(jié)合兩者的優(yōu)點(diǎn)。在內(nèi)部實(shí)現(xiàn)使用命令式告知計算機(jī)如何運(yùn)行,對外暴露的API等則是采用的聲明式編程,能夠用人話讓使用者讀懂結(jié)果。

<div @click="()=>console.log('hello onechuan')">hello pingping<div>

性能和可維護(hù)性

在《編譯原理》書中,了解到命令式代碼的性能優(yōu)于聲明式代碼,這是因?yàn)槁暶魇酱a需要經(jīng)過編譯成計算機(jī)能夠讀懂的命令式代碼。但是呢,聲明式代碼更像是人類能夠讀懂的人話,在盡可能犧牲少量性能的同時降低代碼的維護(hù)成本。

Vue.js框架就是結(jié)合兩者的優(yōu)點(diǎn),對命令式代碼進(jìn)行了封裝,對使用者提供可維護(hù)性更高的聲明式代碼。

4.真實(shí)DOM和虛擬DOM

對于聲明式代碼的更新性能消耗而言:聲明式代碼的更新性能消耗 = 找出差異的性能消耗 + 直接修改的性能消耗,如果我們找到能夠讓找出差異的性能消耗最小化的算法,那么就能夠?qū)⒙暶魇酱a的性能消耗無限趨近于命令式代碼性能消耗。

我們分別從創(chuàng)建頁面和更新頁面兩方面,對真實(shí)DOM和虛擬DOM操作的性能消耗進(jìn)行分析:

狀態(tài)

虛擬DOM(純JS創(chuàng)建VNODE)

真實(shí)DOM(渲染HTML字符串)

創(chuàng)建頁面

新建所有的DOM對象

新建所有的DOM對象

更新頁面

必要的DOM更新

-銷毀所有的舊DOM,新建所有的新DOM

關(guān)于性能:真實(shí)DOM<虛擬DOM<原生JS。

此處簡要的進(jìn)行總結(jié),后續(xù)文章將會有更詳細(xì)的數(shù)據(jù)分析。

5.編譯時和運(yùn)行時

在框架設(shè)計時還要考慮是選擇:純運(yùn)行時、純編譯時還是運(yùn)行時+編譯時,這需要結(jié)合你所期望的待設(shè)計框架的特征做出合適的決策。

運(yùn)行時

所謂運(yùn)行時,就是計算機(jī)所運(yùn)行時的代碼,不需要經(jīng)歷額外的處理,便能夠?qū)崿F(xiàn)我們所期許的結(jié)果。

例如,我們需要將提供的樹形結(jié)構(gòu)的數(shù)據(jù)對象,渲染到渲染成dom樹,那么我們需要設(shè)計一個Render函數(shù)直接進(jìn)行渲染,這樣就能得到我們想要的結(jié)果:

const obj = {
tag:"div",
children:[{
tag:"span",
children:"hello world"
}]
}

Render(obj, document.body)

function Render(obj, root){
const el = document.createElement(obj.tag);
if(typeof obj.children === "string"){
const text = document.createTextNode(obj.children);
el.appendChild(text)
}else if(obj.children){
// 如果是數(shù)組,就進(jìn)行遞歸調(diào)用render,使用el作為root參數(shù)
obj.children.forEach(child=>Render(child, el))
}
// 最后將元素添加到根元素
root.appendChild(el)
}

瀏覽器顯示如下:

編譯時

那么,編譯就是一種轉(zhuǎn)換技術(shù),將高級語言轉(zhuǎn)換低級語言,Vue.js將HTML標(biāo)簽通過編譯轉(zhuǎn)換成樹形結(jié)構(gòu)的數(shù)據(jù)對象。

這樣我們需要編寫一個Compiler函數(shù),用于將HTML標(biāo)簽通過編譯換成樹形結(jié)構(gòu)的數(shù)據(jù)對象。如下:

const html = `
<div>
<span>hello world</span>
</div>`
const obj = compoler(html)
Render(obj, document.body)

這樣就能將:

<div>   
<span>hello pingping</span>
</div>

編譯成:

const obj = {
tag: 'div',
children: [
{tag: 'span', children: 'hello world'}
]
}

結(jié)合Render函數(shù)進(jìn)行渲染,這樣我們就初步設(shè)計了一個運(yùn)行時+編譯時的框架了。

運(yùn)行時+編譯時

所謂在Vue.js是運(yùn)行時+編譯時框架,其實(shí)指的是:

支持運(yùn)行時:使用者可以直接提供樹形結(jié)構(gòu)的數(shù)據(jù)對象而無需編譯;

支持編譯時:使用者可以提供HTML字符串,將其編譯成樹形結(jié)構(gòu)的數(shù)據(jù)對象后再交給運(yùn)行時處理。

為什么Vue.js要設(shè)計成運(yùn)行時+編譯時框架?

這所以這樣設(shè)計也是開源團(tuán)隊進(jìn)行權(quán)衡的結(jié)果,運(yùn)行時無法分析用戶提供的內(nèi)容,而加入編譯后就可以對用戶內(nèi)容進(jìn)行分析和編譯。在編譯的時候提取這些用戶內(nèi)容的信息,再通過Render函數(shù)進(jìn)行渲染。

當(dāng)然,將框架設(shè)計成純編譯時,可以分析用戶內(nèi)容直接編譯成可執(zhí)行的JS代碼,在保證性能的同時犧牲了框架的靈活性和可維護(hù)性,對用戶而言必須對內(nèi)容編譯后才能使用。

對此,Vue.js的設(shè)計是綜合考量,才用的運(yùn)行時+編譯時的框架設(shè)計,在保留運(yùn)行時的靈活性的同時,盡可能不犧牲性能。

6.寫在最后

在本文中,了解到開源團(tuán)隊對于命令式和聲明式、真實(shí)DOM和虛擬DOM、運(yùn)行時和編譯時的權(quán)衡選擇,在盡可能減少性能損耗的同時提供最好的用戶體驗(yàn)和可維護(hù)性、靈活性。

責(zé)任編輯:武曉燕 來源: 前端一碼平川
相關(guān)推薦

2022-04-04 16:53:56

Vue.js設(shè)計框架

2022-04-12 08:08:57

watch函數(shù)options封裝

2022-04-25 07:36:21

組件數(shù)據(jù)函數(shù)

2022-04-18 08:09:44

渲染器DOM掛載Vue.js

2022-04-11 08:03:30

Vue.jscomputed計算屬性

2022-04-14 09:35:03

Vue.js設(shè)計Reflect

2022-04-05 16:44:59

系統(tǒng)Vue.js響應(yīng)式

2022-05-03 21:18:38

Vue.js組件KeepAlive

2022-04-17 09:18:11

響應(yīng)式數(shù)據(jù)Vue.js

2022-04-09 17:53:56

Vue.js分支切換嵌套的effect

2022-04-03 15:44:55

Vue.js框架設(shè)計設(shè)計與實(shí)現(xiàn)

2022-04-16 13:59:34

Vue.jsJavascript

2022-04-26 05:55:06

Vue.js異步組件

2022-04-19 23:01:54

Vue.jsDOM節(jié)點(diǎn)DOM樹

2022-04-20 09:07:04

Vue.js的事件處理

2016-11-01 19:10:33

vue.js前端前端框架

2019-04-01 19:38:28

Vue.jsJavascript前端

2018-04-04 10:32:13

前端JavascriptVue.js

2017-07-04 17:55:37

Vue.js插件開發(fā)

2016-11-04 19:58:39

vue.js
點(diǎn)贊
收藏

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