先說一句題外話,對於 Vue 的探索和應用我只服 ElemeFE
基礎
- 軟體工程學
- 程式碼風格
- 基本功
- Vue.js 官方文件
- ES6
Vue 三大特性
資料的雙向繫結
通過資料繫結連線 View 和 Model, 讓資料的變化自動對映為檢視的更新。
資料驅動的元件系統
用巢狀的元件樹來描述使用者介面,每一個元件對應MVVM中的ViewModel。
基於構建工具的單檔案元件系統
藉助webpack強大的loader API,來定義對不同檔案格式的預處理邏輯,從而將 vue 檔案當作 javascript 模組來使用,從而極大提升了程式碼的可複用性。
開始
俗話說“工欲善其事必先利其器”,再往前遞推,工欲利其器必先得其器。在進行一次 vue 專案的開發之前,如何將 vue 引入是我們面對的第一個問題。
這裡我主要介紹兩種引入方式。
傳統的<script>
大法
遙想當年,在和jQuery一起玩耍的時候,在每擼一個頁面之前,都會先把jq的cdn路徑放在處於</body>
前的<script>
裡面,因為這樣做才可以和她愉快的玩耍。
雖說 jq 和 vue 不是一個概念(庫 vs 框架),但是基於瀏覽器解析js的原理,兩者可以用相同的方式引入。
npm install
NPM(Node Package Manager)是Node.js自帶的一款包管理工具,只需要簡單的在鍵盤上敲下npm install *package name*
就可以將你需要的包安裝至你的專案中,進而藉助模組載入器就可以把她們引入到你的檔案中。
當然,除了npm之外,還有其他的包管理工具,比如 bower 和 yarn,可以根據個人喜好進行選擇。
不過值得一提的是,yarn 是 Facebook 推出的一款包管理工具,他們的工程師在使用 npm 的時候發現了很多需要改進的地方,為了達到預期的效果,打造了 yarn 這款工具。所以,如果你感興趣,可以試試 yarn。
評估
對於上面兩種方式的選擇,你需要權衡一些因素:
- 如果你是嘗試在已有的專案中新增一點新鮮的血液作為預研,建議選擇
<script>
標籤的形式 - 如果你是在從零開始搭建一個 vue 專案,建議選擇用包管理工具的方式
為什麼需要構建
要回答這個問題,就要追溯到另外一個問題:在將程式碼釋出到生產環境之前,我們還需要做什麼?
如果能回答好這個問題,我們就會知道——到底為什麼需要構建?
答案可以大致分為以下幾種:
- 預處理
- 程式碼風格檢測
- 資源壓縮
- 靜態資源替換
因為本文側重點的關係,這裡說一下預處理。
這又是另外一個問題了——為什麼需要預處理?
因為無時不刻都在面臨著瀏覽器的相容問題,比如說ES6,一些語法糖寫起來確實很爽,但是並不是所有瀏覽器都認識她;再者,React 的 jsx,Vue 的單檔案,瀏覽器統統不認識,怎麼辦?只能預處理。
這裡推薦 Vue 官方認證的好基友—— Webpack(其實我是gulp粉…)
如果你用的<script>
來引入Vue,不用關注這個問題,因為你已經協助瀏覽器進行了“線上編譯”。
元件化
Vue 的 slogan 是:輕量高效的前端元件化方案。
這些年,伴隨著 React 對 Web component 的不斷實踐與推動,元件化的思想被前端er們毫無牴觸的接受,相比 React,個人認為 Vue 對元件化的解決方案更加優雅一些——藉助構建工具的單檔案元件系統。
在一個.vue
檔案中,有三個主標籤:<template>, <script>, <style>
,分別對應著當前元件的結構、互動邏輯和樣式。
口說無憑,舉個例子
先來看看 React 的 JSX
render(){
let { item } = this.props;
let children;
if ( items.length > 0 ) {
children = (
<ul>
{ items.map( item =>
<li key={item.id}>{item.name}</li>
) }
</ul>
);
} else {
children = <p>No items found.</p>
}
return (
<div className = `list-container`>
{ children }
</div>
);
}複製程式碼
其實看起來也不是多麼的不堪,能夠利用完整的 JavaScript 功能來構建檢視頁面,也是一件有意義的事情。
相同的業務邏輯,用 Vue 來寫
<template>
<div class="list-container">
<ul v-if="items.length">
<li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>
</div>
</template>複製程式碼
是不是比 React 的 jsx 語法和內聯樣式優雅的多呢?
你需要做的就是根據業務邏輯組織好你的 components tree,接著搭配一款模組化方案,就能實現一個基於 Vue 的單檔案元件系統啦。
當然,Vue 也同樣支援 jsx 語法,你也不必非得采用單檔案的組織形式,一切都取決於你的業務以及你的團隊。
Vue Object
每個 Vue 例項在被建立之前都要經過一系列的初始過程。Vue 在這一週期中提供了一些鉤子函式,這就給我麼提供了執行自定義邏輯的機會。
Vue 是否有“控制器”的概念?
答: 沒有。但是你可以將元件的自定義邏輯分佈並實現在這些鉤子函式中。 、
附上一張描述 Vue 物件生命週期的官方神圖 ↓
做一下簡單的翻譯工作。
beforeCreate
在例項初始化之後,資料觀測(data observer)和 event/watcher 事件配置之前被呼叫。
created
例項已經建立完成之後被呼叫。例項已經完成資料觀測、屬性和方法的運算、watch/event事件回撥,但還沒有開始掛載。
beforeMount
在掛在之前被呼叫
mounted
掛載之後
beforeUpdate
資料更新時呼叫,發生在 vdom 重新渲染和打補丁之前。
updated
由於資料更改導致的 vdom 重新渲染和打補丁,在這之後呼叫。
beforeDestroy
例項銷燬之前呼叫。在這一步,例項仍然完全可用。
destroyed
例項銷燬之後呼叫。
資料流 & 事件流
組裝好了各個元件,你現在面臨的問題是——如何讓這些東西協同工作?
Props
props 是定義在子元件中的屬性,用來定義期望從父元件傳入的資料(在父元件中向子元件新增 v-bind 繫結屬性即可)。
Event
- 使用
$on()
監聽事件 - 使用
$emit()
觸發事件 - 使用
$dispatch()
派發事件,沿父鏈冒泡 - 使用
$broadcast()
廣播事件,傳導給所有的後代
有時候,你也許需要一個幫手—— vuex
當應用比較龐大,資料流和狀態也會越發的難以管理和維護,這個時候你就需要 vuex 了。
21秒精通 Vue.js
接下來從一個新手司機的角度,總結一些可以幫助你快速上手 Vue 的小經驗。
不要一上來就用 vue-cli
連手槍都沒打過,你一上來就問我要他孃的義大利炮?(一個出自《亮劍》的梗)
vue-cli
是 Vue 官方推出的一款可以快速構建一個 vue app 的腳手架,各項配置也是全到沒誰了。
但是,作為一個剛起步的選手,尤其是當你一開始要去搞的專案沒那麼複雜,還是不要用vue-cli
了,原因有以下兩點:
- 如果你像我一樣(對於構建玩的不是特別6),當你在
Terminal
按照指引敲擊完幾條命令之後,看著各種配置檔案,肯定會一臉矇蔽,會非常打擊你的學習熱情。 - 更多的時候,你的專案可能還不需要用到如此完(yōng)整(zhǒng)的構建體系。
所以,自己動手搭一個吧,從最簡單的開始,遲早有一天你也可以寫出一個100%切合自己專案的腳手架。
你不僅需要ES6教程,還需要.babelrc
你是一個有理想的 JavaScript 開發者,你時刻關注著這門語言的發展趨勢,終於有一天,你深深的迷戀上了ES6,她諸多的新特性都令你為之神往,所以你決定緊隨她的腳步。
但事與願違,很多瀏覽器在很大程度上並不認同這位姑娘,所以你需要作為中間人,讓這些觀念老舊的瀏覽器認識到新時代的風尚——這就是編譯(此案例預設為預編譯)。
通常情況下,我們在構建工具中引入babel
對自己的指令碼進行語法上的轉換,實現向後相容。
比如在webpack.config.js
中引入這樣的規則:
{
test: /.js$/,
loader: `babel-loader`,
exclude: /node_modules/,
query: {
presets: [`es2015`, `stage-0`]
}
}複製程式碼
事實證明,在大多數情況下,這樣是ok的。
但,當我們的專案是藉助構建工具實現的單檔案元件系統時,我們的 JavaScript 都寫在了.vue
檔案中,所以當你編譯之後會得到一堆錯誤,這些錯誤都是在你使用ES6語法的地方出現的。
原因是因為我們用vue-loader
去處理.vue
檔案,這本身沒錯。但是,vue-loader
用到了babel-loader
,卻沒有配置babel-loader
的地方,所以呢,gg。
檢視官方文件,就會找到解決辦法。
“babel-loader respects .babelrc, so it is the recommended approach to configure the Babel presets and plugins.”
參加這裡。
綜上,把 babel 相關配置放到 .babelrc 檔案中去。
使用組建之前先註冊
想上車?先買票!
元件 (Components) 是 Vue.js 最強大的功能之一。
如果你沒有使用那個單檔案元件系統,在使用元件的時候,你要這麼做 ↓ (註冊一個全域性元件,Vue.component(tagName, options)
)
Vue.component(`my-component`,{
// options
});複製程式碼
元件在註冊之後,便可以在父例項的模組中以自定義元素<mu-component></my-component>
的形式使用。
要確保在初始化根例項之前註冊了元件:
<div id="example">
<my-component></my-component>
</div>複製程式碼
// 註冊
Vue.component(`my-component`, {
template: `<p>Hello Vue component</p>`
});
// 建立根例項
new Vue({
el: `#example`
});複製程式碼
你也可以通過使用元件例項選項註冊,可以使元件僅在另一個例項/元件的作用域中可用,這也是單檔案元件系統的註冊方式,即區域性註冊。
官方文件寫的已經非常詳細了,如果你仍然對這裡有疑慮,給你一個傳送門。
父子元件是怎麼協同工作的?
父子元件的關係可以總結為 props down, events up。
父元件通過 props 向下傳遞資料給子元件,子元件通過 events 給父元件傳送訊息。
這就好比,老子給兒子生活費(props),兒子一有事就告訴老子:“爸,我沒錢了”、“爸,有人打我”、“爸,我餓了”(events)。
讓你更方便的除錯 Vue
官方提供了一款 Chrome 外掛,用於除錯你的 Vue app —— Vue.js devtools。
最後
全文是從個人的視角出發,描述對 Vue 的認識以及在開發過程中一些問題的理解。
如果有不正確、或是與你理解有偏差的地方,希望你能指出這些問題,共同學習。