摘要:由于是需要兼容的后臺(tái)系統(tǒng),該項(xiàng)目并不能使用到等技術(shù),因此我在上的經(jīng)驗(yàn)大都是使用原生的編寫的,可以看見一個(gè)組件分為兩部分視圖部分,和數(shù)據(jù)部分。
在公司里幫項(xiàng)目組里開發(fā)后臺(tái)系統(tǒng)的前端項(xiàng)目也有一段時(shí)間了。 vue這種數(shù)據(jù)驅(qū)動(dòng),組件化的框架和react很像,
從一開始的快速上手基本的開發(fā),到后來開始自定義組件,對(duì)element UI的組件二次封裝以滿足項(xiàng)目需求,期間也是踩了不少坑。
由于將來很長一段時(shí)間可能再也不會(huì)接觸前端了,趁著現(xiàn)在對(duì)vue還很熟練的時(shí)候,趕緊將這期間的收獲記錄下來。
按照我的理解,vue的特點(diǎn)在于,高層次的抽象模型,組件化,數(shù)據(jù)驅(qū)動(dòng)與響應(yīng)式。
注意:本文中所有涉及到{ {的,實(shí)際上不包括中間的空格,因?yàn)閔exo會(huì)無腦把這個(gè)語法當(dāng)成hexo的一種特殊語法
vue是什么及特點(diǎn) vue是什么簡(jiǎn)單的來說,vue是一套用于前端開發(fā)的框架。
學(xué)習(xí)一門技術(shù)首先應(yīng)該對(duì)該技術(shù)有著一個(gè)清晰正確的認(rèn)識(shí)和思路,否則猶如浮沙之上建高樓。下面就來談?wù)勎覍?duì)vue這個(gè)框架的理解。
vue它的驚艷之處在于,對(duì)上,它提供了一套非常優(yōu)秀的與傳統(tǒng)前端截然不同的前端開發(fā)模型,對(duì)下,它屏蔽了傳統(tǒng)前端開發(fā)的各種丑陋的技術(shù)。
在實(shí)現(xiàn)復(fù)雜的頁面需求時(shí),vue幫你從傳統(tǒng)前端的各種HACK般的奇淫技巧解脫出來,vue提供的抽象開發(fā)模型擁有強(qiáng)大的 表達(dá)能力,能夠如絲順滑般的完成各種復(fù)雜的需求。
總而言之,vue之于傳統(tǒng)前端,類似C語言之于匯編語言,就像C語言提供了一個(gè)強(qiáng)大的表達(dá)能力強(qiáng)的語言模型一樣,vue同樣提供了一個(gè)強(qiáng)悍的表達(dá)前端的框架模型,這是抽象的威力。
因此,學(xué)習(xí)vue的80%的重心,都在學(xué)習(xí)這個(gè)強(qiáng)悍的vue模型上。
從我個(gè)人對(duì)vue的理解,它的幾個(gè)重要特點(diǎn)有:
抽象的組件。這是vue框架模型中的一個(gè)基礎(chǔ),vue的一切都是基于vue組件的。你在vue組件上可以使用vue提供的各種特性,vue會(huì)將其轉(zhuǎn)換成瀏覽器能夠識(shí)別的結(jié)果通過瀏覽器渲染出來。
數(shù)據(jù)驅(qū)動(dòng)。這是vue的理念之一,數(shù)據(jù)才是項(xiàng)目的核心,也是狀態(tài)的最終保存者。而視圖,只不過是一種能夠由數(shù)據(jù)延遲計(jì)算出來的最終結(jié)果而已,它本身不存儲(chǔ)狀態(tài)。
響應(yīng)式。既然渲染結(jié)果只是數(shù)據(jù)的衍生產(chǎn)物,那么當(dāng)數(shù)據(jù)改變時(shí),渲染結(jié)果自然而然的也要改變。這種機(jī)制就是響應(yīng)式。
組件化。vue本身提供的 抽象特性 。從我個(gè)人的理解來看,自定義組件在vue中的地位,類似于函數(shù)在C,java之類的語言之中的地位。
它還有幾個(gè)其它的的特點(diǎn):
易用和功能兼顧。在我傳統(tǒng)的思維里,易用的東西一般會(huì)犧牲一部分功能,而功能強(qiáng)大的東西會(huì)需要很大的成本學(xué)習(xí),魚和熊掌不可兼得。
然而vue用實(shí)際行動(dòng)狠狠給了我一耳光,只要模型設(shè)計(jì)的正交完美,完全能夠兼顧易用性和功能性。
與傳統(tǒng)前端的良好兼容。
我目前所做的項(xiàng)目中,由于需求的復(fù)雜化項(xiàng)目需要從easy UI迭代到vue,原本我做好了大刀闊斧大規(guī)模重構(gòu)的準(zhǔn)備,不過,經(jīng)過查閱文檔和幾個(gè)小demo實(shí)驗(yàn)我發(fā)現(xiàn),這玩意居然能夠和傳統(tǒng)前端并存!
結(jié)果是非常令人開心的,我逐步的,慢慢的將項(xiàng)目從easy UI迭代到vue版本,一個(gè)頁面一個(gè)頁面的替換,對(duì)項(xiàng)目的影響降低到了最小。
下面的例子定義了一個(gè)簡(jiǎn)單的組件,x-my-component。
由于是需要兼容easy UI的后臺(tái)系統(tǒng),該項(xiàng)目并不能使用到webpack + babel + es6等技術(shù),因此我在vue上的經(jīng)驗(yàn)大都是使用原生的js編寫的,
{ { message }}
可以看見一個(gè)組件分為兩部分:視圖部分,和數(shù)據(jù)部分。
視圖部分使用html定義,但是vue會(huì)對(duì)一些特別的語法賦予vue自己的意義。如 { { message }} 表示將數(shù)據(jù)message綁定到視圖的這個(gè)地方來。
這里是使用原生js編寫的,因此數(shù)據(jù)部分和視圖部分通過id選擇器關(guān)聯(lián)起來,定義了一個(gè)x-my-component全局組件。
從這里就可以初步感受到數(shù)據(jù)驅(qū)動(dòng)。組件的狀態(tài)都是存放的數(shù)據(jù)中的,而視圖只負(fù)責(zé)渲染,本身不保存狀態(tài)。
當(dāng)數(shù)據(jù)不變時(shí),渲染結(jié)果一定不變;當(dāng)數(shù)據(jù)改變時(shí),渲染結(jié)果就要發(fā)生改變。
由于vue是組件化的,組件可以層層嵌套。不過,最終的根節(jié)點(diǎn)得是app節(jié)點(diǎn),這樣才能渲染出結(jié)果。它的定義方式不太相同:
從這里可以看出,自定義的全局組件在vue的其它組件中可以直接使用,就像使用一個(gè)已經(jīng)存在的html標(biāo)簽一樣。
數(shù)據(jù)綁定從數(shù)據(jù)驅(qū)動(dòng)的觀點(diǎn),我們很容易分析出數(shù)據(jù)流向:
數(shù)據(jù)源 --> vue對(duì)象 --> DOM
{ { message }} { { message.split("").reverse().join("") }}
將數(shù)據(jù)綁定到一般的內(nèi)容上,用簡(jiǎn)單的 { {}} 的語法就可以了。
將數(shù)據(jù)綁定到屬性上,需要用特殊的 v-bind 語法。上面將 message 數(shù)據(jù)綁定到了title屬性上。
由于這個(gè)語法太常用了, v-bind:title 可直接縮寫為 :title 。
用 -v-html 語法,綁定原始的html數(shù)據(jù)。
能綁定的不僅僅是屬性鍵值,還可以是 單個(gè)表達(dá)式 。注意 只能 是單個(gè)表達(dá)式。
這些表達(dá)式只能訪問全局變量的一個(gè)白名單,如Math和Date, 不能訪問用戶自定義的全局變量 。
在傳統(tǒng)的前端編程中,需要仔細(xì)預(yù)防的一點(diǎn)是xss攻擊。xss攻擊的原理是:
用戶輸入的數(shù)據(jù)直接被插入到了DOM中。
用戶輸入的數(shù)據(jù)中含有html或js代碼,那么它會(huì)直接作為DOM的一部分,被渲染或被執(zhí)行出來。
利用這一點(diǎn),就能夠創(chuàng)造一個(gè)指向攻擊者頁面的一張圖片或者鏈接,從而盜取用戶的cookies或sid,或者誘導(dǎo)用戶點(diǎn)擊釣魚網(wǎng)址。
因此,為預(yù)防xss,任何用戶給定的數(shù)據(jù)展現(xiàn)到頁面上都需要仔細(xì)的處理。但是如果使用vue,就不必太操心這個(gè)問題。
因?yàn)椋瑅ue提供了一個(gè)更高層次的前端模型,所有的業(yè)務(wù)代碼都需要通過vue處理。我們只需要看vue對(duì)xss的處理情況就可以了。
從上面我們可以看到,數(shù)據(jù)到視圖渲染中必須使用vue的插值語法:
普通的文本插值。vue會(huì)過濾xss攻擊,因此可以安全使用。
使用v-html語法將html插入渲染后的DOM中。這當(dāng)然會(huì)造成xss攻擊,因此,使用v-html語法時(shí)要非常的小心。
條件與循環(huán)現(xiàn)在你看到我了
- { { todo.text }}
用 v-if 綁定的數(shù)據(jù),控制此元素是否顯示。
用 v-for 綁定的特殊語法,用于控制循環(huán), v-for 的元素會(huì)被重復(fù)。如上所示,todos是一個(gè)數(shù)組。
響應(yīng)式上面的例子中可以數(shù)據(jù)綁定的語法,實(shí)際上,將數(shù)據(jù)綁定到視圖上的操作并不少見,這些操作,和后端技術(shù)常用的模樣引擎類似,如python的Jinja2, java的freemarker。
但是,vue的數(shù)據(jù)綁定的還有一大不同點(diǎn)點(diǎn)是 響應(yīng)式 。
由于視圖渲染是從數(shù)據(jù)計(jì)算出來的產(chǎn)物,類似一個(gè)傳入數(shù)據(jù)傳出渲染結(jié)果的純函數(shù),因此,當(dāng)數(shù)據(jù)改變時(shí),渲染結(jié)果也會(huì)改變,所得到的結(jié)果是頁面展示的界面也會(huì)發(fā)送改變。
數(shù)據(jù)綁定還不能完全走通一個(gè)vue組件的數(shù)據(jù)流程,從上面的數(shù)據(jù)綁定我們可以發(fā)現(xiàn)一個(gè)事實(shí):
數(shù)據(jù)由vue對(duì)象流向視圖進(jìn)而渲染出來。
那么,反過來呢?如果讓數(shù)據(jù)從頁面流向vue對(duì)象?這就是下面要說到的事件處理。
事件處理事件處理的數(shù)據(jù)流向是這樣的:
用戶操作頁面產(chǎn)生數(shù)據(jù) --> 頁面 --> vue對(duì)象
{ { message }}
通過 v-on 語法,綁定事件。按鈕的數(shù)據(jù)傳入到vue對(duì)象中。
這個(gè)語法太常用了,所以 v-on:click 可縮寫成 @click 。
通過 v-model 語法,將表單的數(shù)據(jù)傳入到vue對(duì)象中。v-model的數(shù)據(jù)流動(dòng)是雙向的,相當(dāng)于:value數(shù)據(jù)綁定和@input事件綁定的語法糖。
能夠與用戶交互的組件都能夠產(chǎn)生數(shù)據(jù)。當(dāng)用戶操作組件時(shí),組件的相應(yīng)事件被觸發(fā),進(jìn)而執(zhí)行綁定到事件的相應(yīng)函數(shù)。
在函數(shù)內(nèi)部你可以做任何處理邏輯,比如說改變vue對(duì)象記錄的狀態(tài),也就是數(shù)據(jù)。
那么,這樣,一個(gè)完整的數(shù)據(jù)流程就跑通了:
用戶操作vue組件。
相應(yīng)的事件被觸發(fā),從而導(dǎo)致綁定事件的函數(shù)被觸發(fā)。
函數(shù)執(zhí)行業(yè)務(wù)代碼,改變vue組件的狀態(tài),也就是前面說到的數(shù)據(jù)綁定中的數(shù)據(jù)。
數(shù)據(jù)被改變,綁定了該數(shù)據(jù)的視圖也會(huì)發(fā)送改變,視圖被重新渲染。
頁面發(fā)生相應(yīng)改變,用戶觀察到了自己操作的反饋結(jié)果。
再談響應(yīng)式 virtual DOM我們知道,數(shù)據(jù)被綁定到視圖上,視圖本身不存儲(chǔ)狀態(tài),當(dāng)數(shù)據(jù)不變時(shí),渲染結(jié)果不變;當(dāng)數(shù)據(jù)改變時(shí),視圖也需要重新渲染。
好了,現(xiàn)在頭腦里可能會(huì)有一個(gè)簡(jiǎn)單的思路了:
當(dāng)數(shù)據(jù)改變時(shí),觸發(fā)數(shù)據(jù)的setter,setter除了更改數(shù)據(jù)變動(dòng)外,還需要執(zhí)行數(shù)據(jù)更新邏輯。
重新執(zhí)行渲染函數(shù),從新的數(shù)據(jù)中計(jì)算出新的渲染結(jié)果。
將渲染結(jié)果插入瀏覽器DOM樹中。
但是,我們仔細(xì)考察下第三步。瀏覽器的DOM樹改變后,瀏覽器才會(huì)真正的重新渲染這個(gè)DOM,計(jì)算各種css,各種布局,層層調(diào)用各種繪圖函數(shù)重新繪制GUI等等。。。
總而言之,這個(gè)步驟是非常非常耗時(shí)的。
那么,一個(gè)優(yōu)化的手段是,盡可能讓真正的DOM改變的最少,這樣瀏覽器只需要渲染最少的結(jié)果就能達(dá)到效果,提升性能。
因此,vurtual DOM就出現(xiàn)了。如下:
當(dāng)數(shù)據(jù)改變時(shí),觸發(fā)數(shù)據(jù)的setter,setter除了更改數(shù)據(jù)變動(dòng)外,還需要執(zhí)行數(shù)據(jù)更新邏輯。
重新執(zhí)行渲染函數(shù),從新的數(shù)據(jù)中計(jì)算出新的渲染結(jié)果。
渲染結(jié)果被放在virtual DOM中,vue將新的DOM和就的DOM進(jìn)行diff。
將diff后的差異結(jié)果更新到真正的瀏覽器DOM樹中。
可以看到,整個(gè)流程中的一大重點(diǎn)是diff算法。關(guān)于DOM的diff算法,我沒有接觸過。。。。。。。
之前研究過文本diff算法是基于LCS算法的動(dòng)態(tài)規(guī)劃優(yōu)化,之后有興趣可以研究下DOM的diff算法。
從上面我們知道,當(dāng)直接設(shè)置一個(gè)vue屬性的值時(shí),會(huì)觸發(fā)getter函數(shù)。
實(shí)際上,getter函數(shù)是js的一個(gè)機(jī)制。在修改數(shù)組或?qū)ο髸r(shí),也有類似的機(jī)制保證vue能檢測(cè)到數(shù)據(jù)的更新以觸發(fā)渲染。
然而,有幾種情況,由于js的限制無法檢測(cè)到,實(shí)際編程中要特別注意,否則就會(huì)感覺碰到了一個(gè)玄學(xué)bug。。。
數(shù)組。
利用索引來直接設(shè)置數(shù)組元素。如 this.todos[index] = "B"。解決方案是:Vue.set(this.todos, index, "B"),通過vue的函數(shù)設(shè)置。
直接修改數(shù)組的長度。如 this.todos.length = 10。替代方案建議使用不可變數(shù)據(jù)結(jié)構(gòu)。
對(duì)象。vue無法檢測(cè)到對(duì)象屬性的添加或刪除。添加的話,可以使用Vue.set,刪除的話,可以使用不可變數(shù)據(jù)結(jié)構(gòu)。
最后此篇博文梳理了vue的基本特性,但是對(duì)于vue最重量級(jí)的功能----組件化,沒有涉及到。對(duì)于組件化的相關(guān)梳理留到下篇博文梳理。
注:該文于2018-04-09撰寫于我的github靜態(tài)頁博客,現(xiàn)同步到我的segmentfault來。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/95866.html
摘要:觸發(fā)事件可以攜帶數(shù)據(jù),這些數(shù)據(jù)被用于傳遞給綁定了事件的其它組件的回調(diào)函數(shù)上,進(jìn)而被傳遞給其它組件。父組件可以在回調(diào)函數(shù)里做任何事情,頗有靈活性。一般情況下,父組件會(huì)在回調(diào)函數(shù)中更新自己的狀態(tài)數(shù)據(jù)。 上一篇博文梳理了vue的數(shù)據(jù)驅(qū)動(dòng)和響應(yīng)式相關(guān)的特性,這一篇博文就來梳理vue的一個(gè)很重要的特性,組件化。自定義組件之于vue,其意義不亞于函數(shù)之于C,java之類的編程語言。函數(shù)是計(jì)算機(jī)科學(xué)...
摘要:苗條的框架正是作者的初始目的,苗條包括代碼編寫量打包大小等等。是已經(jīng)編譯后的組件有什么缺點(diǎn)是一個(gè)剛起步不久的前端框架,無論在維護(hù)人員還是社區(qū)上都是大大不如三大框架,這里列舉一下本人認(rèn)為的存在的缺點(diǎn)。 Svelte 的作者也是 rollup 的作者 Rich Harris,前端界的輪子哥。sevlte 項(xiàng)目首次提交于 2016 年 11 月 16 日,目前版本是 3.6.1(2019-0...
摘要:的核心庫只關(guān)注視圖層,并且非常容易學(xué)習(xí),非常容易與其它庫或已有項(xiàng)目整合。的目標(biāo)是通過盡可能簡(jiǎn)單的實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。并不是框架,只是和他旁邊的生態(tài)環(huán)境組成了一個(gè)框架,下面,貼一個(gè)官方的漸進(jìn)式框架介紹圖吧,方便理解。 前言 本人學(xué)習(xí)了一段時(shí)間的vue,并嘗試寫了一些小Demo之后,將vue投入了幾個(gè)項(xiàng)目之后,一直在邊學(xué)習(xí)邊使用,經(jīng)過看了vue,vuex,vue-route...
摘要:的核心庫只關(guān)注視圖層,并且非常容易學(xué)習(xí),非常容易與其它庫或已有項(xiàng)目整合。的目標(biāo)是通過盡可能簡(jiǎn)單的實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。并不是框架,只是和他旁邊的生態(tài)環(huán)境組成了一個(gè)框架,下面,貼一個(gè)官方的漸進(jìn)式框架介紹圖吧,方便理解。 前言 本人學(xué)習(xí)了一段時(shí)間的vue,并嘗試寫了一些小Demo之后,將vue投入了幾個(gè)項(xiàng)目之后,一直在邊學(xué)習(xí)邊使用,經(jīng)過看了vue,vuex,vue-route...
摘要:原文博客地址如何理解如何實(shí)現(xiàn)是否解讀過的源碼與框架的區(qū)別實(shí)現(xiàn)實(shí)現(xiàn)獨(dú)立初始化實(shí)例兩者的區(qū)別數(shù)據(jù)和視圖的分離,解耦開放封閉原則,對(duì)擴(kuò)展開放,對(duì)修改封閉在中在代碼中操作視圖和數(shù)據(jù),混在一塊了以數(shù)據(jù)驅(qū)動(dòng)視圖,只關(guān)心數(shù)據(jù)變化, 原文博客地址:https://finget.github.io/2018/05/31/mvvm-vue/ MVVM 如何理解 MVVM 如何實(shí)現(xiàn) MVVM 是否解讀過 ...
閱讀 2318·2021-10-09 09:41
閱讀 3497·2021-09-13 10:34
閱讀 1990·2019-08-30 12:59
閱讀 616·2019-08-29 17:27
閱讀 1123·2019-08-29 16:07
閱讀 3025·2019-08-29 13:15
閱讀 1378·2019-08-29 13:14
閱讀 1632·2019-08-26 12:18