欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Vue.js輕量高效的前端組件化方案

 更新時間:2018年12月10日 08:57:07   作者:掉進書洞里的貓  
這篇文章主要介紹了深入理解Vue.js輕量高效的前端組件化方案 ,需要的朋友可以參考下

Vue.js通過簡潔的API提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng)。在前端紛繁復(fù)雜的生態(tài)中,Vue.js有幸受到一定程度的關(guān)注,目前在GitHub上已經(jīng)有5000+的star。本文將從各方面對Vue.js做一個深入的介紹。

Vue.js 是我在2014年2月開源的一個前端開發(fā)庫,通過簡潔的 API 提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng)。在前端紛繁復(fù)雜的生態(tài)中,Vue.js有幸受到一定程度的關(guān)注,目前在 GitHub上已經(jīng)有5000+的star。本文將從各方面對Vue.js做一個深入的介紹。

開發(fā)初衷

2013年末,我還在Google Creative Lab工作。當(dāng)時在項目中使用了一段時間的Angular,在感嘆數(shù)據(jù)綁定帶來生產(chǎn)力提升的同時,我也感到Angular的API設(shè)計過于繁瑣,使得學(xué)習(xí)曲線頗為陡峭。出于對Angular數(shù)據(jù)綁定原理的好奇,我開始 “造輪子”,自己實現(xiàn)了一個非常粗糙的、基于依賴收集的數(shù)據(jù)綁定庫。這就是Vue.js的前身。同時在實際開發(fā)中,我發(fā)現(xiàn)用戶界面完全可以用嵌套的組件樹來描述,而一個組件恰恰可以對應(yīng)MVVM中的ViewModel。于是我決定將我的數(shù)據(jù)綁定實驗改進成一個真正的開源項目,其核心思想便是 “數(shù)據(jù)驅(qū)動的組件系統(tǒng)”。

MVVM 數(shù)據(jù)綁定

MVVM的本質(zhì)是通過數(shù)據(jù)綁定鏈接View和Model,讓數(shù)據(jù)的變化自動映射為視圖的更新。Vue.js在數(shù)據(jù)綁定的API設(shè)計上借鑒了Angular的指令機制:用戶可以通過具有特殊前綴的HTML 屬性來實現(xiàn)數(shù)據(jù)綁定,也可以使用常見的花括號模板插值,或是在表單元素上使用雙向綁定:

<!-- 指令 -->
<span v-text="msg"></span>
<!-- 插值 -->
<span>{{msg}}</span>
<!-- 雙向綁定 -->
<input v-model="msg"> 

插值本質(zhì)上也是指令,只是為了方便模板的書寫。在模板的編譯過程中,Vue.js會為每一處需要動態(tài)更新的DOM節(jié)點創(chuàng)建一個指令對象。每當(dāng)一個指令對象觀測的數(shù)據(jù)變化時,它便會對所綁定的目標(biāo)節(jié)點執(zhí)行相應(yīng)的DOM操作?;谥噶畹臄?shù)據(jù)綁定使得具體的DOM操作都被合理地封裝在指令定義中,業(yè)務(wù)代碼只需要涉及模板和對數(shù)據(jù)狀態(tài)的操作即可,這使得應(yīng)用的開發(fā)效率和可維護性都大大提升。

與Angular不同的是,Vue.js的API里并沒有繁雜的module、controller、scope、factory、service等概念,一切都是以“ViewModel 實例”為基本單位:

<!-- 模板 -->
<div id="app">
 {{msg}}
</div>
// 原生對象即數(shù)據(jù)
var data = {
 msg: 'hello!'
}
// 創(chuàng)建一個 ViewModel 實例
var vm = new Vue({
 // 選擇目標(biāo)元素
 el: '#app',
 // 提供初始數(shù)據(jù)
 data: data
})

渲染結(jié)果:

<div id="app">
 hello!
</div> 

在渲染的同時,Vue.js也已經(jīng)完成了數(shù)據(jù)的動態(tài)綁定:此時如果改動data.msg的值,DOM將自動更新。是不是非常簡單易懂呢?除此之外,Vue.js對自定義指令、過濾器的API也做了大幅的簡化,如果你有Angular的開發(fā)經(jīng)驗,上手會非常迅速。

數(shù)據(jù)觀測的實現(xiàn)

Vue.js的數(shù)據(jù)觀測實現(xiàn)原理和Angular有著本質(zhì)的不同。了解Angular的讀者可能知道,Angular的數(shù)據(jù)觀測采用的是臟檢查(dirty checking)機制。每一個指令都會有一個對應(yīng)的用來觀測數(shù)據(jù)的對象,叫做watcher;一個作用域中會有很多個watcher。每當(dāng)界面需要更新時,Angular會遍歷當(dāng)前作用域里的所有watcher,對它們一一求值,然后和之前保存的舊值進行比較。如果求值的結(jié)果變化了,就觸發(fā)對應(yīng)的更新,這個過程叫做digest cycle。臟檢查有兩個問題:
1.任何數(shù)據(jù)變動都意味著當(dāng)前作用域的每一個watcher需要被重新求值,因此當(dāng)watcher的數(shù)量龐大時,應(yīng)用的性能就不可避免地受到影響,并且很難優(yōu)化。
2.當(dāng)數(shù)據(jù)變動時,框架并不能主動偵測到變化的發(fā)生,需要手動觸發(fā)digest cycle才能觸發(fā)相應(yīng)的DOM 更新。Angular通過在DOM事件處理函數(shù)中自動觸發(fā)digest cycle部分規(guī)避了這個問題,但還是有很多情況需要用戶手動進行觸發(fā)。

Vue.js采用的則是基于依賴收集的觀測機制。從原理上來說,和老牌MVVM框架Knockout是一樣的。依賴收集的基本原理是:
1.將原生的數(shù)據(jù)改造成 “可觀察對象”。一個可觀察對象可以被取值,也可以被賦值。
2.在watcher的求值過程中,每一個被取值的可觀察對象都會將當(dāng)前的watcher注冊為自己的一個訂閱者,并成為當(dāng)前watcher的一個依賴。
3.當(dāng)一個被依賴的可觀察對象被賦值時,它會通知所有訂閱自己的watcher重新求值,并觸發(fā)相應(yīng)的更新。
4.依賴收集的優(yōu)點在于可以精確、主動地追蹤數(shù)據(jù)的變化,不存在上述提到的臟檢查的兩個問題。但傳統(tǒng)的依賴收集實現(xiàn),比如Knockout,通常需要包裹原生數(shù)據(jù)來制造可觀察對象,在取值和賦值時需要采用函數(shù)調(diào)用的形式,在進行數(shù)據(jù)操作時寫法繁瑣,不夠直觀;同時,對復(fù)雜嵌套結(jié)構(gòu)的對象支持也不理想。

Vue.js利用了ES5的Object.defineProperty方法,直接將原生數(shù)據(jù)對象的屬性改造為getter和setter,在這兩個函數(shù)內(nèi)部實現(xiàn)依賴的收集和觸發(fā),而且完美支持嵌套的對象結(jié)構(gòu)。對于數(shù)組,則通過包裹數(shù)組的可變方法(比如push)來監(jiān)聽數(shù)組的變化。這使得操作Vue.js的數(shù)據(jù)和操作原生對象幾乎沒有差別[注:在添加/刪除屬性,或是修改數(shù)組特定位置元素時,需要調(diào)用特定的函數(shù),如obj.$add(key, value)才能觸發(fā)更新。這是受ES5的語言特性所限。],數(shù)據(jù)操作的邏輯更為清晰流暢,和第三方數(shù)據(jù)同步方案的整合也更為方便。

組件系統(tǒng)

在大型的應(yīng)用中,為了分工、復(fù)用和可維護性,我們不可避免地需要將應(yīng)用抽象為多個相對獨立的模塊。在較為傳統(tǒng)的開發(fā)模式中,我們只有在考慮復(fù)用時才會將某一部分做成組件;但實際上,應(yīng)用類 UI 完全可以看作是全部由組件樹構(gòu)成的:

因此,在Vue.js的設(shè)計中將組件作為一個核心概念??梢哉f,每一個Vue.js應(yīng)用都是圍繞著組件來開發(fā)的。

注冊一個Vue.js組件十分簡單:

Vue.component('my-component', {
 // 模板
 template: '<div>{{msg}} {{privateMsg}}</div>',
 // 接受參數(shù)
 props: {
  msg: String<br> 

 },
 // 私有數(shù)據(jù),需要在函數(shù)中返回以避免多個實例共享一個對象
 data: function () {
  return {
   privateMsg: 'component!'
  }
 }
})

注冊之后即可在父組件模板中以自定義元素的形式調(diào)用一個子組件:

<my-component msg="hello"></my-component>

渲染結(jié)果:

<div>hello component!</div>

Vue.js的組件可以理解為預(yù)先定義好了行為的ViewModel類。一個組件可以預(yù)定義很多選項,但最核心的是以下幾個:

•模板(template):模板聲明了數(shù)據(jù)和最終展現(xiàn)給用戶的DOM之間的映射關(guān)系。
•初始數(shù)據(jù)(data):一個組件的初始數(shù)據(jù)狀態(tài)。對于可復(fù)用的組件來說,這通常是私有的狀態(tài)。
•接受的外部參數(shù)(props):組件之間通過參數(shù)來進行數(shù)據(jù)的傳遞和共享。參數(shù)默認(rèn)是單向綁定(由上至下),但也可以顯式地聲明為雙向綁定。
•方法(methods):對數(shù)據(jù)的改動操作一般都在組件的方法內(nèi)進行??梢酝ㄟ^v-on指令將用戶輸入事件和組件方法進行綁定。
•生命周期鉤子函數(shù)(lifecycle hooks):一個組件會觸發(fā)多個生命周期鉤子函數(shù),比如created,attached,destroyed等等。在這些鉤子函數(shù)中,我們可以封裝一些自定義的邏輯。和傳統(tǒng)的MVC相比,可以理解為 Controller的邏輯被分散到了這些鉤子函數(shù)中。
•私有資源(assets):Vue.js當(dāng)中將用戶自定義的指令、過濾器、組件等統(tǒng)稱為資源。由于全局注冊資源容易導(dǎo)致命名沖突,一個組件可以聲明自己的私有資源。私有資源只有該組件和它的子組件可以調(diào)用。

除此之外,同一顆組件樹之內(nèi)的組件之間還可以通過內(nèi)建的事件API來進行通信。Vue.js提供了完善的定義、復(fù)用和嵌套組件的API,讓開發(fā)者可以像搭積木一樣用組件拼出整個應(yīng)用的界面。這個思路的可行性在Facebook開源的React當(dāng)中也得到了印證。

基于構(gòu)建工具的單文件組件格式

Vue.js的核心庫只提供基本的API,本身在如何組織應(yīng)用的文件結(jié)構(gòu)上并不做太多約束。但在構(gòu)建大型應(yīng)用時,推薦使用Webpack+vue-loader這個組合以使針對組件的開發(fā)更高效。

Webpack是由Tobias Koppers開發(fā)的一個開源前端模塊構(gòu)建工具。它的基本功能是將以模塊格式書寫的多個JavaScript文件打包成一個文件,同時支持CommonJS和AMD格式。但讓它與眾不同的是,它提供了強大的loader API來定義對不同文件格式的預(yù)處理邏輯,從而讓我們可以將CSS、模板,甚至是自定義的文件格式當(dāng)做JavaScript模塊來使用。Webpack 基于loader還可以實現(xiàn)大量高級功能,比如自動分塊打包并按需加載、對圖片資源引用的自動定位、根據(jù)圖片大小決定是否用base64內(nèi)聯(lián)、開發(fā)時的模塊熱替換等等,可以說是目前前端構(gòu)建領(lǐng)域最有競爭力的解決方案之一。

我在Webpack的loader API基礎(chǔ)上開發(fā)了vue-loader插件,從而讓我們可以用這樣的單文件格式 (*.vue) 來書寫Vue組件:

<style>
.my-component h2 {
 color: red;
}
</style>
<template>
 <div class="my-component">
 <h2>Hello from {{msg}}</h2>
 <other-component></other-component>
 </div>
</template>
<script>
// 遵循 CommonJS 模塊格式
var otherComponent = require('./other-component')
// 導(dǎo)出組件定義
module.exports = {
 data: function () {
 return {
  msg: 'vue-loader'
 }
 },
 components: {
 'other-component': otherComponent
 }
}
</script>

 同時,還可以在*.vue文件中使用其他預(yù)處理器,只需要安裝對應(yīng)的Webpack loader即可:

<style lang="stylus">
.my-component h2
 color red
</style>
<template lang="jade">
div.my-component
 h2 Hello from {{msg}}
</template>
<script lang="babel">
// 利用 Babel 編譯 ES2015
export default {
 data () {
 return {
  msg: 'Hello from Babel!'
 }
 }
}
</script>

這樣的組件格式,把一個組件的模板、樣式、邏輯三要素整合在同一個文件中,即方便開發(fā),也方便復(fù)用和維護。另外,Vue.js本身支持對組件的異步加載,配合Webpack的分塊打包功能,可以極其輕松地實現(xiàn)組件的異步按需加載。

其他特性

Vue.js還有幾個值得一提的特性:

1.異步批量DOM更新:當(dāng)大量數(shù)據(jù)變動時,所有受到影響的watcher會被推送到一個隊列中,并且每個watcher只會推進隊列一次。這個隊列會在進程的下一個 “tick” 異步執(zhí)行。這個機制可以避免同一個數(shù)據(jù)多次變動產(chǎn)生的多余DOM操作,也可以保證所有的DOM寫操作在一起執(zhí)行,避免DOM讀寫切換可能導(dǎo)致的layout。
2.動畫系統(tǒng):Vue.js提供了簡單卻強大的動畫系統(tǒng),當(dāng)一個元素的可見性變化時,用戶不僅可以很簡單地定義對應(yīng)的CSS Transition或Animation效果,還可以利用豐富的JavaScript鉤子函數(shù)進行更底層的動畫處理。
3.可擴展性:除了自定義指令、過濾器和組件,Vue.js還提供了靈活的mixin機制,讓用戶可以在多個組件中復(fù)用共同的特性。

與Web Components的異同

對Web Components有了解的讀者看到這里可能會產(chǎn)生疑問:Vue.js的組件和Web Components的區(qū)別在哪里呢?這里簡要地做一下分析。

Web Components是一套底層規(guī)范,本身并不帶有數(shù)據(jù)綁定、動畫系統(tǒng)等上層功能,因此更合適的比較對象可能是Polymer。Polymer在API和功能上和Vue.js比較相似,但它對Web Components的硬性依賴使得它在瀏覽器支持方面有一定的問題——在不支持Web Components規(guī)范的瀏覽器中,需要加載龐大的polyfill,不僅在性能上會有影響,并且有些功能,比如ShadowDOM,polyfill并沒有辦法完美支持。同時,Web Components規(guī)范本身尚未定稿,一些具體設(shè)計上仍存在不小的分歧。相比之下,Vue.js在支持的瀏覽器中(IE9+)沒有任何依賴。

除此之外,在支持Web Components的環(huán)境中,我們也可以很簡單地利用Web Components底層API將一個Vue.js組件封裝在一個真正的自定義元素中,從而實現(xiàn)Vue.js組件和其他框架的無縫整合。

總結(jié)

在發(fā)布之初,Vue.js原本是著眼于輕量的嵌入式使用場景。在今天,Vue.js也依然適用于這樣的場景。由于其輕量(22kb min+gzip)、高性能的特點,對于移動場景也有很好的契合度。更重要的是,設(shè)計完備的組件系統(tǒng)和配套的構(gòu)建工具、插件,使得Vue.js在保留了其簡潔API的同時,也已經(jīng)完全有能力擔(dān)當(dāng)起復(fù)雜的大型應(yīng)用的開發(fā)。

從誕生起到現(xiàn)在的一年半歷程中,Vue.js經(jīng)歷了一次徹底的重構(gòu),多次API的設(shè)計改進,目前已經(jīng)趨于穩(wěn)定,測試覆蓋率長期保持在100%,GitHub Bug數(shù)量長期保持在個位數(shù),并在世界各地都已經(jīng)有公司/項目將Vue.js應(yīng)用到生產(chǎn)環(huán)境中。在2015年晚些時候,Vue.js將發(fā)布1.0版本,敬請期待。

【參考鏈接】

Vue.js官方網(wǎng)站:http://vuejs.org

Vue.js GitHub倉庫:https://github.com/yyx990803/vue

Webpack官方網(wǎng)站: http://webpack.github.io

vue-loader單頁組件示例:https://github.com/vuejs/vue-loader-example

總結(jié)

以上所述是小編給大家介紹的Vue.js輕量高效的前端組件化方案,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 最基礎(chǔ)的vue.js雙向綁定操作

    最基礎(chǔ)的vue.js雙向綁定操作

    這篇文章主要為大家詳細介紹了最基礎(chǔ)的vue.js雙向綁定操作,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • vue使用urlEncode問題

    vue使用urlEncode問題

    這篇文章主要介紹了vue使用urlEncode問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue props傳值失敗 輸出undefined的解決方法

    vue props傳值失敗 輸出undefined的解決方法

    今天小編就為大家分享一篇vue props傳值失敗 輸出undefined的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 詳解vuex的簡單使用

    詳解vuex的簡單使用

    這篇文章主要介紹了詳解vuex的簡單使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • vue3如何使用vant-picker封裝省市二級聯(lián)動

    vue3如何使用vant-picker封裝省市二級聯(lián)動

    這篇文章主要介紹了vue3如何使用vant-picker封裝省市二級聯(lián)動,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 簡單理解vue中track-by屬性

    簡單理解vue中track-by屬性

    這篇文章主要幫助大家簡單的理解vue中track-by屬性,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • vue2.0 實現(xiàn)富文本編輯器功能

    vue2.0 實現(xiàn)富文本編輯器功能

    這篇文章主要介紹了vue2.0 實現(xiàn)富文本編輯器功能,本文給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-05-05
  • 用Vue.extend構(gòu)建消息提示組件的方法實例

    用Vue.extend構(gòu)建消息提示組件的方法實例

    本篇文章主要介紹了用Vue.extend構(gòu)建消息提示組件的方法實例,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • vue項目中使用bpmn-自定義platter的示例代碼

    vue項目中使用bpmn-自定義platter的示例代碼

    這篇文章主要介紹了vue項目中使用bpmn-自定義platter的實例代碼,本文通過代碼截圖相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • Vue3中watch監(jiān)聽使用詳解

    Vue3中watch監(jiān)聽使用詳解

    watch 函數(shù)用來偵聽特定的數(shù)據(jù)源,并在回調(diào)函數(shù)中執(zhí)行副作用,下面這篇文章主要給大家介紹了關(guān)于Vue3中watch監(jiān)聽使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08

最新評論