【小(xiǎo)編推薦】Vue.js:輕量高(gāo)效的(de)前端↑ββ"組件(jiàn)化(huà)方案

2015-08-13   |&δ±nbsp;  發布者:梁國(guó)芳&​‌πnbsp;  |   查看​δ♥(kàn):3320次

IT新聞
 

Vue.js 是(shì)我在2014年¶↔↓∞(nián)2月(yuè)開(kāi)源δ>的(de)一(yī)個(gè)前端開(kāi)發¥↔α庫,通(tōng)過簡潔的(de) API 提♠​ ​供高(gāo)效的(de)數(shù)據綁定§λ>和(hé)靈活的(de)組件(jiàn)系統γ∏。在前端紛繁複雜(zá)的(de)生(shēng)态✔φ↕中,Vue.js有(yǒu)幸受到(dào)一(yī)定程度的(de)關γ✔∑γ注,目前在 GitHub上(shàng)已經∏<α÷有(yǒu)5000+的(de)star。本文("π>wén)将從(cóng)各方面對(duì)Vu≥♠₽<e.js做(zuò)一(yī)個(gè)深入的(de)介紹。

開(kāi)發初衷

2013年(nián)末,我還(hái)在Google ∏•βΩCreative Lab工(gōng)作(zuò)。當時(shí)在♦★‌項目中使用(yòng)了(le)一(yī)段時(↕×shí)間(jiān)的(de)Angular★®',在感歎數(shù)據綁定帶來(lái)生(shēng)産力提÷↔λ​升的(de)同時(shí),我也(yě)感到(d‌δ₩✔ào)Angular的(de)API設計(jì)過于繁瑣,使得(de)學習§φ(xí)曲線頗為(wèi)陡峭。出于對(duì)AngulaΩ•♦r數(shù)據綁定原理(lǐ)的(de)好(hǎo)奇,我開(kāi)始 δδ“造輪子(zǐ)”,自(zì)己實現(÷≠₹∏xiàn)了(le)一(yī)個(gè)非常粗糙的(de)、π<≥±基于依賴收集的(de)數(shù)據綁定庫。這(zhè)就(jiù)是(sh÷↓εì)Vue.js的(de)前身(shēn)。同時≤±(shí)在實際開(kāi)發中,我發現(xiàn)用≥→→δ(yòng)戶界面完全可(kě)以用(yò©↓↑βng)嵌套的(de)組件(jiàn)樹(shù)來(lái)描述,而一(yī‍γ)個(gè)組件(jiàn)恰恰可(kě)以對(duì)應¶✘♣"MVVM中的(de)ViewModel。于是(s₩→ hì)我決定将我的(de)數(shù)據綁定實驗改進成 β<一(yī)個(gè)真正的(de)開(kāi)源  項目,其核心思想便是(shì) “數(shù)據驅動的(de)組εφ×♥件(jiàn)系統”。

MVVM 數(shù)據綁定

MVVM的(de)本質是(shì)通(tōng)過數(shù)據綁定鏈接Vi&••☆ew和(hé)Model,讓數(shù)據的(de"→)變化(huà)自(zì)動映射為(wèi)視(shì)圖∞☆的(de)更新。Vue.js在數(shù)據綁定≥↓±✔的(de)API設計(jì)上(shàng)借鑒了(le)Angular的(≠∏♥de)指令機(jī)制(zhì):用(yò←§$±ng)戶可(kě)以通(tōng)過具有(yǒu)特殊前綴的(de)HTML Ωβ↕屬性來(lái)實現(xiàn)數(shù)據綁定,也(yě)可 ∏(kě)以使用(yòng)常見(jiàn)的(de)花(huā)括号模闆插值♣←Ω,或是(shì)在表單元素上(shàng)使用(yòng)雙向綁定:

<!-- 指令 -->
<span v-tex↓εt="msg"></∞σ×‌span>
<!-- 插值 --& ®™gt;
<span>{{msg}}</spanγ >
<!-- 雙向綁定 -->
&l↕ ≥£t;input v-model="msg"φ♣≤;>  

插值本質上(shàng)也(yě)是(shì)指令,隻是(shì)為(wè>₽λ♣i)了(le)方便模闆的(de)書(shū)寫。在模闆↑±的(de)編譯過程中,Vue.js會(huì)為(wèi)每₽× 一(yī)處需要(yào)動态更新的(de)DOM節點創建一(yī)個(÷ gè)指令對(duì)象。每當一(yī)個(gè₽£)指令對(duì)象觀測的(de)數(shù)據變化(huà)時(shí),它π®₩λ便會(huì)對(duì)所綁定的(de)目标節點執行Ω♠↓¥(xíng)相(xiàng)應的(de)DOM操作(zuò)。基于指↕¥令的(de)數(shù)據綁定使得(de)具體(tǐ)的(de)DOβ∞"₽M操作(zuò)都(dōu)被合理(lǐ)地(dì'•↕¥)封裝在指令定義中,業(yè)務代碼隻需要(yào)涉​₽÷£及模闆和(hé)對(duì)數(shù)♥φ♥據狀态的(de)操作(zuò)即可(kě),這(β↔zhè)使得(de)應用(yòng)的(de)開(kāi)®≈↓₩發效率和(hé)可(kě)維護性都(dōu)×≈Ω大(dà)大(dà)提升。

圖1 Vue.js的(de)MVVM架構

 

與Angular不(bù)同的(de)是 ®(shì),Vue.js的(de)API™↔ 裡(lǐ)并沒有(yǒu)繁雜(zá)的(de)module、contro™ £ller、scope、factory、service等概念,一(yī)切都≈‍¥γ(dōu)是(shì)以“ViewModel 實例&rdqu♥↔o;為(wèi)基本單位:

 

<!-- 模闆 -->
<diπ☆v id="app">
    {{÷δmsg}}
</div>

 

// 原生(shēng)對(duì)象即數(shù)據
var d​₹ata = {
    msg: 'hello!'
}
≤ ¶≥
// 創建一(yī)個(gè) ViewMo→↑♦∑del 實例
var vm = new Vue({
    // 選擇目✔♦'∑标元素
    el: '#app',
'✘
    // 提供初始數(shù)據
    data: data
‌‍})

 

渲染結果:

 

<div id="app&<♥ quot;>
    helloδ≤≠!
</div>  

 

在渲染的(de)同時(shí),Vue.js也(yě)已經完成了♠<(le)數(shù)據的(de)動态綁定:此✘♣γ時(shí)如(rú)果改動data.msg的•‌(de)值,DOM将自(zì)動更新。是(shì)不(bù)是(s ☆✘✘hì)非常簡單易懂(dǒng)呢(ne)?除此之外(wài),Vu≥∑e.js對(duì)自(zì)定義指令、過濾器(qì)的(de♥↑Ω)API也(yě)做(zuò)了(le)大(dà)幅的(d"→e)簡化(huà),如(rú)果你(nǐ)有(yǒu​α₹)Angular的(de)開(kāi)發經驗,上(&←shàng)手會(huì)非常迅速。

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

Vue.js的(de)數(shù)據觀測實現(xiàn)原理(lǐ)和(héΩ↔≥)Angular有(yǒu)著(zhe)本質φ→的(de)不(bù)同。了(le)解Angular的(de)讀•'(dú)者可(kě)能(néng)知(zhī)道(dào),An≠§&gular的(de)數(shù)據觀測采₽™₩用(yòng)的(de)是(shì)髒檢查(dirty checking)₩ σ↔機(jī)制(zhì)。每一(yī)個(gè)指令都(dōu)會(h'✔ ↓uì)有(yǒu)一(yī)個(gè)對(duì$©δ•)應的(de)用(yòng)來(lái)觀測數(shù)據& ₹的(de)對(duì)象,叫做(zuò)wat>λcher;一(yī)個(gè)作(zuò∑♥)用(yòng)域中會(huì)有(yǒu)很(hěn)多(duō)個(gè♦♦♠§)watcher。每當界面需要(yào)更新時(shí),Angular會•★β(huì)遍曆當前作(zuò)用(yòn✘♣g)域裡(lǐ)的(de)所有(yǒu)waφ★‍‌tcher,對(duì)它們一(yī)一(yī)求值,然後和(hé)之前保存₹↑¥ 的(de)舊(jiù)值進行(xíng)比較✔α✔≤。如(rú)果求值的(de)結果變化(huà)了(le),就(jiù)觸發對✘ (duì)應的(de)更新,這(zhè)個(gè)過程叫做(zuò)♠✔αdigest cycle。髒檢查有(yǒu)兩個(g‌ 'è)問(wèn)題:

 

  1. 任何數(shù)據變動都(dōu)意味著(zhe)當前作(zuò)用(yòn ©g)域的(de)每一(yī)個(gè)watche♥'→¥r需要(yào)被重新求值,因此當watcher的(de)數(γ↕‌ shù)量龐大(dà)時(shí),應用(yòng)的(de)性能(né₩←'ng)就(jiù)不(bù)可(kě)避免地(dì)受到(dào)影(yǐn×♣g)響,并且很(hěn)難優化(huà)。
  2. 當數(shù)據變動時(shí),框架并不(bù)能(néng•'₽)主動偵測到(dào)變化(huà)的(de)發生&✔✔≈(shēng),需要(yào)手動觸發digest cycle才能(n $éng)觸發相(xiàng)應的(de)DOM 更新。Angular通(£λ&tōng)過在DOM事(shì)件(jiàn<$)處理(lǐ)函數(shù)中自(zì)動觸發digest↕α"& cycle部分(fēn)規避了(le)這(zhè)個(gè)問(wèn)題™✘'¥,但(dàn)還(hái)是(shì)有(yǒu)很(hěn)多(duō)☆$<情況需要(yào)用(yòng)戶手動進行(xíng)觸發。

 

Vue.js采用(yòng)的(de)則是(shì)基于"‍•‌依賴收集的(de)觀測機(jī)制(zhì)。從(α↔cóng)原理(lǐ)上(shàng)來(lái)說(shuō),和(hé)老∏→(lǎo)牌MVVM框架Knockout是(shì)一(yī)樣的(de)↕∏ 。依賴收集的(de)基本原理(lǐ)是(shì):

 

  1. 将原生(shēng)的(de)數(shù)據改造成 “可(kě)↓$§♣觀察對(duì)象”。一(yī)個(gè)可(kě)觀察對(du±≠ì)象可(kě)以被取值,也(yě)可(kě)以被賦值。
  2. 在watcher的(de)求值過程中,每一(yī)個(←→gè)被取值的(de)可(kě)觀察對(duì)象都(≈₩πdōu)會(huì)将當前的(de)watcher注冊為(wèi)'•自(zì)己的(de)一(yī)個(gè)訂閱者,并成為(wèiγ>☆)當前watcher的(de)一(yī)個(gèππ♠÷)依賴。
  3. 當一(yī)個(gè)被依賴的(de)可(kě)觀察對(<€¥ duì)象被賦值時(shí),它會(huì)通(t♥✔ōng)知(zhī)所有(yǒu)訂閱自(zì)己的(  de)watcher重新求值,并觸發相(xiànπ™g)應的(de)更新。
  4. 依賴收集的(de)優點在于可(kě)以精确、主動地(dì)追蹤數(s≠↕↓ hù)據的(de)變化(huà),不(bù)存在上(shàng)述提到(d γào)的(de)髒檢查的(de)兩個(gè)問 §↕(wèn)題。但(dàn)傳統的(de)依賴收集實現(xiàn),比如(rú)≠'×Knockout,通(tōng)常需要(yào)包裹原生✔ δ®(shēng)數(shù)據來(lái)制(zhì)造可(kě)觀察α&↓♦對(duì)象,在取值和(hé)賦值時(shí)需要(yào)采用γ ☆‍(yòng)函數(shù)調用(yòng)的(de)形≠®式,在進行(xíng)數(shù)據操作(λ‍™zuò)時(shí)寫法繁瑣,不(bù)夠直觀;同時(shí),對(duì γ←)複雜(zá)嵌套結構的(de)對(duì)象支持也(yě)不(bùγδσ‍)理(lǐ)想。

 

Vue.js利用(yòng)了(le)ES5的(de)Obj× ect.defineProperty方法,☆≠直接将原生(shēng)數(shù)據對(duì)象的(" ©de)屬性改造為(wèi)getter和(hé)setter,在這(zhè)兩€✘±₽個(gè)函數(shù)內(nèi)部實現(xiàn)依賴✔ ÷​的(de)收集和(hé)觸發,而且完美(m♦<ěi)支持嵌套的(de)對(duì)象結構。對(duì)于數(shù)組,則通↓¥Ω(tōng)過包裹數(shù)組的(de)可(kě)變方法(比↓✘£如(rú)push)來(lái)監聽(tīng)數(shù)組的↓ש(de)變化(huà)。這(zhè)使得(de≈δα)操作(zuò)Vue.js的(de)數(shù)據和₹Ω÷∞(hé)操作(zuò)原生(shēng)對(duì)象幾乎沒有(♥☆<☆yǒu)差别[注:在添加/删除屬性,或是(shì)修改數(shù)組特定位置₽"₩元素時(shí),需要(yào)調用(yòng)特定的(de)函數(shù₹∑),如(rú)obj.$add(key, value)才能(nén'πg)觸發更新。這(zhè)是(shì)受ES₽§5的(de)語言特性所限。],數(shù)據操作(∞≈‌↑zuò)的(de)邏輯更為(wèi)清晰流暢λ✔,和(hé)第三方數(shù)據同步方案的(de)∑↔♣€整合也(yě)更為(wèi)方便。

圖2 Vue.js的(de)數(shù)據觀測和(hé)>>數(shù)據綁定實現(xiàn)圖解

 

組件(jiàn)系統

在大(dà)型的(de)應用(yòng)中,為(wèiβΩ)了(le)分(fēn)工(gōng)、複用(yòn¥ g)和(hé)可(kě)維護性,我們不(bù)可↕•≠₽(kě)避免地(dì)需要(yào)将應用(yòng)抽象為(w‌<→♦èi)多(duō)個(gè)相(xiàng)對(duì)獨立的(de)模塊。&&>在較為(wèi)傳統的(de)開(kāi)發模式中,我們隻有(yǒu)↕™在考慮複用(yòng)時(shí)才會(huì)将某一≥©(yī)部分(fēn)做(zuò)成組件(jiàn¶☆);但(dàn)實際上(shàng),應用(yònβ≥'γg)類 UI 完全可(kě)以看(kàn)作(zuò)是(shì)全部由組εφ‍λ件(jiàn)樹(shù)構成的(de):

 

 圖3 UI = 組件(jià↓$n)樹(shù)

因此,在Vue.js的(de)設計(jì)中π∞♣↔将組件(jiàn)作(zuò)為(wèi)∏§© 一(yī)個(gè)核心概念。可(kě)以說(sh★>$uō),每一(yī)個(gè)Vue.js應用(yòng)都(dōu)是(✔α™shì)圍繞著(zhe)組件(jiàn)★φ來(lái)開(kāi)發的(de)。

注冊一(yī)個(gè)Vue.js組件(jiàn)十分(fēn)簡單©₹×:

 

 

Vue.component('my-compon¶εΩent', {
    // 模闆
    template: '<‌Ω↕↓div>{{msg}} {{privateMsg}}</div&g≠↕t;',
    // 接受參數(shù)
    props:•× {
        msg: String&↕≥↑®lt;br>    

    },
    // 私有( ≈δyǒu)數(shù)據,需要(yào)在函數(shù)中返回以避©₽免多(duō)個(gè)實例共享一(yī)個(gè)對(duì)象§®←
    data: function () {
        reφ¶∏​turn {
            privateMsg: 'com‍♣₹ponent!'
        }
 ≤♠   }
})

 

 

注冊之後即可(kě)在父組件(jiàn)模闆中以自(zì)定©↓↕義元素的(de)形式調用(yòng)一(yī)個(gè)子(zǐ)組件>₽(jiàn): 

 

<my-component msg="hello&qu∞§ot;></my-component>

 

渲染結果:

 

<div>hello component!<₹‍ ";/div>

 

Vue.js的(de)組件(jiàn)可(kě)以理(lǐ)解為β§¥(wèi)預先定義好(hǎo)了(le)行(x→÷≤ íng)為(wèi)的(de)ViewMod"≥el類。一(yī)個(gè)組件(jiàn)可(kě)以預定義很(hěn)↓≈✘σ多(duō)選項,但(dàn)最核心的(de)是(shì)以下(xià)幾個(♣≤☆♥gè):

 

 

 

除此之外(wài),同一(yī)顆組件(jiàn)樹(shù)之內(nè↕™'±i)的(de)組件(jiàn)之間(jiān)還(hái)可(k←σ↔δě)以通(tōng)過內(nèi)建的(de)事(shì)件(jiàn♥±±)API來(lái)進行(xíng)通(tōng↑± )信。Vue.js提供了(le)完善的(de)♠≠‌定義、複用(yòng)和(hé)嵌套組件(™★jiàn)的(de)API,讓開(kāi)發者可(kě)以像搭積木Ω∑≠'(mù)一(yī)樣用(yòng)組件(jiàn)拼出整↔∞♣<個(gè)應用(yòng)的(de)界面。這(zhè)個(g∞€ ₽è)思路(lù)的(de)可(kě)行(xíng)性在Facebooπ™≥™k開(kāi)源的(de)React當中也(yě)得(de)到( •←§dào)了(le)印證。

基于構建工(gōng)具的(de)單文(wén)件(jiàn)組件(j★<&iàn)格式

Vue.js的(de)核心庫隻提供基本的(£<≥de)API,本身(shēn)在如(rú)何組織應用(yòng)的(de)文÷ (wén)件(jiàn)結構上(shàng)并不(bù)做(zuò₩§©)太多(duō)約束。但(dàn)在構建大(dà)型應用(yòn‍®≥g)時(shí),推薦使用(yòng)Webpa☆↕Ω ck+vue-loader這(zhè)個(& ∞gè)組合以使針對(duì)組件(jiàn)的(de)開(kā∞±®☆i)發更高(gāo)效。

Webpack是(shì)由Tobias Koppers開(kāi)發的 ±(de)一(yī)個(gè)開(kāi)源前端模塊構建工(gōng™↔ε)具。它的(de)基本功能(néng)是(shì)将以模塊★₹格式書(shū)寫的(de)多(duō)個(g≠λ•¶è)JavaScript文(wén)件(jiàn)打包成一(yī)個(gπ×₹è)文(wén)件(jiàn),同時(sh↑'í)支持CommonJS和(hé)AMD格式。但(dàn)讓它與衆β♦α<不(bù)同的(de)是(shì),它提供了(le)強大($λ"≠dà)的(de)loader API來(lái)定義對(duì×↑)不(bù)同文(wén)件(jiàn)格式的(de)預處π¥理(lǐ)邏輯,從(cóng)而讓我們可(kě)以将CSS、模闆,甚至ε ♣是(shì)自(zì)定義的(de)文(wé&σφ¥n)件(jiàn)格式當做(zuò)JavaScrip>&☆γt模塊來(lái)使用(yòng)。Web£βpack 基于loader還(hái)可(kě)以實現(xiàn)大(dà)量♦™高(gāo)級功能(néng),比如(rú)自(zì)動分(fēn€¥)塊打包并按需加載、對(duì)圖片資源引用(yòng)的(de)自(z♦≠‌‍ì)動定位、根據圖片大(dà)小(xiǎo)決定是÷>(shì)否用(yòng)base64內(nèi)聯、開(kā÷&i)發時(shí)的(de)模塊熱(rè)替換等等,可(k↕↕≈ě)以說(shuō)是(shì)目前前端構建領✘×✘域最有(yǒu)競争力的(de)解決方案之一(yī)。

我在Webpack的(de)loader API基礎上(shàn ε™‍g)開(kāi)發了(le)vue-loader插件(jiàn),從(có↓♦♣ng)而讓我們可(kě)以用(yòng)這(zhè)樣≤δγφ的(de)單文(wén)件(jiàn)格式 (*.→•vue) 來(lái)書(shū)寫Vue組件(α∑±♦jiàn):

 

<style>
.my-component h2 {
 ±®>↓ color: red;
}
</style&g$¥t;

<template>
  <div c↓σ<≤lass="my-compone¶γ×↕nt">
    <h2>Hell​​₹o from {{msg}}</h2>
    <ot ↕‍her-component><φ"≤/other-component>
  Ω‌↕≤</div>
</template>

<✔≤;script>
// 遵循 CommonJS  ≠↓φ模塊格式
var otherCompo™$&φnent = require('./other-component')→≥

// 導出組件(jiàn)定義
m≠↑‍odule.exports = {
  data: function () ♦σ☆${
    return {
      msg: •↕•₩'vue-loader'
    }
  },
  compo★$β>nents: {
    'other-compone↕αnt': otherComponent
  }
}
</₩©∑script>

 

同時(shí),還(hái)可(kě)以在*.vue文(δ wén)件(jiàn)中使用(yòng)其他(t♦ ↓ā)預處理(lǐ)器(qì),隻需要(yào)安裝對(duì)應的(∑♠♣de)Webpack loader即可(kě): 

 

<style lang="stylus&q€αuot;>
.my-component ←>∑h2
  color red
</style> ≠

<template lang="γε→δjade">
div.my-compo¶≠≈nent
  h2 Hello from {{msg}}
</te"€mplate>

<script lang="baδδ®bel">
// 利用(yòng) Babel > ♥☆編譯 ES2015
export deβ↔↓•fault {
  data () {
    return {
 ✘επ
      msg: 'Hello from Ba ₩bel!'
    }
  }
}
<σλ©;/script>

 

 

這(zhè)樣的(de)組件(jiàn)格≤®λ÷式,把一(yī)個(gè)組件(jiàn)的(de)模闆、樣式、邏輯三π↕β要(yào)素整合在同一(yī)個(gè)文(wén)件(jiàn)≈φ€¶中,即方便開(kāi)發,也(yě)方便複用(yòng)±§α±和(hé)維護。另外(wài),Vue.js本身(shēn)支‌↓≠₽持對(duì)組件(jiàn)的(de)異步加α₩←←載,配合Webpack的(de)分(fēn)塊打包功能(néng),可(↓★εkě)以極其輕松地(dì)實現(xiàn)♦↑組件(jiàn)的(de)異步按需加載。

其他(tā)特性

Vue.js還(hái)有(yǒu)幾個(gè)值得(de)一(yβ≈↑↕ī)提的(de)特性:

 

  1. 異步批量DOM更新:當大(dà)量數(shù)據變動時(shí),所有(yǒu₽♠ )受到(dào)影(yǐng)響的(de)watcher會($'→✔huì)被推送到(dào)一(yī)個(©✘>gè)隊列中,并且每個(gè)watcher隻會(huì)推進隊列≈"¥一(yī)次。這(zhè)個(gè)隊列會(huì)在進程的(de)下(xπ®£←ià)一(yī)個(gè) “tick” 異步執行☆∞§ (xíng)。這(zhè)個(gè)機(jī)制(zhì)可( ₹βkě)以避免同一(yī)個(gè)數(shù)據多(d♠λ uō)次變動産生(shēng)的(de)多(duō)餘×¶←★DOM操作(zuò),也(yě)可(kě)以保證所有(yǒu)的(™•±≠de)DOM寫操作(zuò)在一(yī)起執→φ✘行(xíng),避免DOM讀(dú)寫切換可(kě)能(néng)導緻的(d∞¶'βe)layout。
  2. 動畫(huà)系統:Vue.js提供了(le)簡單卻強大(dà)的(d↔↓♠e)動畫(huà)系統,當一(yī)個(gè®∑)元素的(de)可(kě)見(jiàn)性變化(huà)時(sh>↓ í),用(yòng)戶不(bù)僅可(kě)以很(hěn)簡單地(dì)定義對''₽♣(duì)應的(de)CSS Transition或Animation≥∑效果,還(hái)可(kě)以利用(yòng)豐富的(de)JavaS≤≈♦ cript鈎子(zǐ)函數(shù)進行(>↓xíng)更底層的(de)動畫(huà)處理(lǐ)。 <
  3. 可(kě)擴展性:除了(le)自(zì)定義指令、過濾器(qì)和(hé)組©$件(jiàn),Vue.js還(hái)提供了(le)靈活的(de)mixi€∏•n機(jī)制(zhì),讓用(yòng)戶可(kě)以在多(du&÷'↓ō)個(gè)組件(jiàn)中複用(yòng)共同的(de)特性。

 

與Web Components的(de)異同

對(duì)Web Components有(yǒu)了(le)解的(de)讀✔>(dú)者看(kàn)到(dào)這(zhè)裡(lǐ)可(k™€∏ě)能(néng)會(huì)産生(sh&πφβēng)疑問(wèn):Vue.js的(₽✔de)組件(jiàn)和(hé)Web Component' s的(de)區(qū)别在哪裡(lǐ)呢(neφ∏♥ε)?這(zhè)裡(lǐ)簡要(yào)地(dì)做(zuò)一(yī)下(x​↑↕ià)分(fēn)析。

Web Components是(shì)一(Ω₽yī)套底層規範,本身(shēn)并不(bù)帶有(yǒu←✔)數(shù)據綁定、動畫(huà)系統等上(sh¶✔'àng)層功能(néng),因此更合适的(de)比★ ★較對(duì)象可(kě)能(néng)是(shì)Polyφ✔↔mer。Polymer在API和(hé)功能(nén<§∑←g)上(shàng)和(hé)Vue.js比較相(xià₹™→∏ng)似,但(dàn)它對(duì)Web Components的(de)♦₹硬性依賴使得(de)它在浏覽器(qì)支持方面有( ♣→yǒu)一(yī)定的(de)問(wèn)題—&m≈↕¥'dash;在不(bù)支持Web Components'®₩規範的(de)浏覽器(qì)中,需要(yào)加載≤↓÷龐大(dà)的(de)polyfill,​Ω不(bù)僅在性能(néng)上(shàng)會(huì)有(yǒu)影δ÷β≥(yǐng)響,并且有(yǒu)些(xiē)功能(néng),比≥‍如(rú)ShadowDOM,polyf★"λill并沒有(yǒu)辦法完美(měi)支持。同時(shí),Web C× ≥omponents規範本身(shēn)尚$< 未定稿,一(yī)些(xiē)具體(tǐ)設計(jìλ€★)上(shàng)仍存在不(bù)小(xiǎo)♠®ε的(de)分(fēn)歧。相(xiàng)比之下(xià),Vue.j>♥s在支持的(de)浏覽器(qì)中(IE9+)沒有(yǒu)任何依賴。

除此之外(wài),在支持Web Components的(φπde)環境中,我們也(yě)可(kě)以很£₽γφ(hěn)簡單地(dì)利用(yòng)Web Components底層APIσγπ将一(yī)個(gè)Vue.js組件(jiàn)封裝在一γ ₩(yī)個(gè)真正的(de)自(zì)定☆↑>≤義元素中,從(cóng)而實現(xiàn)Vue.js組件(jià‌&→≠n)和(hé)其他(tā)框架的(de)無縫整合。

總結

在發布之初,Vue.js原本是(shì)著≥≈♠×(zhe)眼于輕量的(de)嵌入式使用(yòng)場(chǎng)景。在今天,"≈♠↑Vue.js也(yě)依然适用(yòng)于這(zhè)樣的(de‌‍)場(chǎng)景。由于其輕量(22kb min+λ∑αgzip)、高(gāo)性能(néng)的(de)特點,對(du δì)于移動場(chǎng)景也(yě)有(yǒu)很(hěn)∑™好(hǎo)的(de)契合度。更重要(yào)的(de)是(shì)≠®,設計(jì)完備的(de)組件(jiàn)系統和(hé✔♠♣)配套的(de)構建工(gōng)具、插件(jiàn),使得(de)V×§ε±ue.js在保留了(le)其簡潔API的(de)同時(shí),也σ≠≈(yě)已經完全有(yǒu)能(néng§α★↕)力擔當起複雜(zá)的(de)大(dà)型應用(yòn€γ££g)的(de)開(kāi)發。

從(cóng)誕生(shēng)起到(dào)現(xiàn)在的(de)一​÷(yī)年(nián)半曆程中,Vue.js經曆了(le)一∞₽(yī)次徹底的(de)重構,多(duō)次API的↔♥™(de)設計(jì)改進,目前已經趨于穩定,測試覆蓋率長(chδ≤¥γáng)期保持在100%,GitHub Bug數(shù)量長(™<cháng)期保持在個(gè)位數(shù δ §),并在世界各地(dì)都(dōu)已經有(yǒu)公司/項目将±±Vue.js應用(yòng)到(dào)±¶生(shēng)産環境中。在2015年(nián∏☆©↓)晚些(xiē)時(shí)候,Vue.js将發布1βε™.0版本,敬請(qǐng)期待。