元件可以擴充 <code>HTML</code> 元素,封裝可重用的代碼。
vue.js的核心元件:
模闆(template)——模闆聲明了資料和最終展現給使用者的DOM之間的映射關系。
初始資料(data)——一個元件的初始資料狀态。對于可複用的元件來說,通常是私有的狀态。
接受的外部參數(props)——元件之間通過參數來進行資料的傳遞和共享。參數預設是單向綁定(由上至下),但也可以顯式聲明為雙向綁定。
方法(methods)——對資料的改動操作一般都在元件的方法内進行。可以通過<code>v-on</code>指令将使用者輸入事件群組件方法進行綁定。
生命周期鈎子函數(lifecycle hooks)——一個元件會觸發多個生命周期鈎子函數,比如<code>created</code>、<code>attached</code>、<code>destroyed</code>等。在這些鈎子函數中,我們可以封裝一些自定義的邏輯。和傳統的MVC相比,這可以了解為<code>Controller</code>的邏輯被分散到了這些鈎子函數中。
私有資源(assets):Vue.js當中将使用者自定義的指令、過濾器、元件等統稱為資源。由于全局注冊資源容易導緻命名沖突,一個元件可以聲明自己的私有資源。私有資源隻有該元件和它的子元件可以調用。
除此之外,同一棵元件樹之内的元件之間還可以通過内建的事件API來進行通信。Vue.js提供了完善的定義、複用和嵌套元件的API,讓開發者可以像搭積木一樣用元件拼出整個應用的界面。這個思路的可行性在Facebook開源的React當中也得到了印證。
Vue.js的核心庫隻提供基本的API,本身在如何組織應用的檔案結構上并不做太多限制。但在建構大型應用時,推薦使用 <code>Webpack+vue-loader</code> 這個組合以使針對元件的開發更高效。
Webpack是由Tobias Koppers開發的一個開源前端子產品建構工具。它的基本功能是将以子產品格式書寫的多個JavaScript檔案打包成一個檔案,同時支援CommonJS和AMD格式。但讓它與衆不同的是,它提供了強大的loader API來定義對不同檔案格式的預處理邏輯,進而讓我們可以将CSS、模闆,甚至是自定義的檔案格式當做JavaScript子產品來使用。Webpack 基于loader還可以實作大量進階功能,比如自動分塊打包并按需加載、對圖檔資源引用的自動定位、根據圖檔大小決定是否用base64内聯、開發時的子產品熱替換等等,可以說是目前前端建構領域最有競争力的解決方案之一。
Vue.js還有幾個值得一提的特性:
異步批量DOM更新:當大量資料變動時,所有受到影響的<code>watcher</code>會被推送到一個隊列中,并且每個<code>watcher</code>隻會推進隊列一次。這個隊列會在程序的下一個 “tick” 異步執行。這個機制可以避免同一個資料多次變動産生的多餘DOM操作,也可以保證所有的DOM寫操作在一起執行,避免DOM讀寫切換可能導緻的layout。
動畫系統:Vue.js提供了簡單卻強大的動畫系統,當一個元素的可見性變化時,使用者不僅可以很簡單地定義對應的CSS <code>Transition</code>或<code>Animation</code>效果,還可以利用豐富的JavaScript鈎子函數進行更底層的動畫處理。
可擴充性:除了自定義指令、過濾器群組件,Vue.js還提供了靈活的mixin機制,讓使用者可以在多個元件中複用共同的特性。
元件執行個體的作用域是孤立的。這意味着不能(也不應該)在子元件的模闆内直接引用父元件的資料。要讓子元件使用父元件的資料,我們需要通過子元件的 <code>props</code> 選項。
子元件要顯式地用 <code>props</code> 選項聲明它期待獲得的資料。
Vue 中子元件可以通過通過事件和父元件進行通信的。向父元件發消息是通過 <code>this.$dispatch</code>,而向子元件發送消息是通過 <code>this.$boardcast</code>。
Vue 把雙向綁定稱作 reactive,可以翻譯為響應式資料綁定。内部是通過 ES5 定義的 <code>getter</code> 和 <code>setter</code> 方法實作的,是以不支援 IE8 及以下浏覽器,這種實作方式有兩個容易犯錯的地方:
如果在 data 上直接添加和删除屬性是無法被檢測到的,一般删除是不會的,但是可能會動态添加,這個時候應該通過 <code>vm.$set(“name”, value)</code> 的方式來添加。
無法檢測到對象内部的變化,也就是隻能檢測 data 的屬性變化,如果 <code>data.a</code> 是一個對象,那麼 <code>data.a.b = 1</code> 這種變化是無法被檢測到的。這種情況下應該建立一個新的對象并指派給 data.a 就行了。
Vue 對DOM的更新是異步的! 這個異步是在一個異步隊列中進行的,不過這個異步隊列會在目前的 <code>Event Loop</code> 中執行完,是以如果修改了 Data 立刻去DOM中做查詢操作是不對的,這個時候DOM還沒有更新,正确的做法是這樣做:
或者這樣: