開頭
如果讓我用一句話總結(jié)我對 Vue 的理解,我可能會這樣說“它真的非常好理解”或者“它就像一個工具,我可以隨心所欲的使用它,而又不會受制于它”。在我學(xué)習(xí) Vue 的過程中,我非常的開心,因為它很有意思,很優(yōu)雅。
這篇文章是我個人對 Vue 的了解。當(dāng)我第一次學(xué)習(xí) Vue 的時候,我希望能有一篇這樣的文章幫助指導(dǎo)我學(xué)習(xí)。如果你想要通過權(quán)威的方式學(xué)習(xí) Vue 的話,那么你可以參考 Vue 官網(wǎng)的指南,非常的詳細(xì),簡單明了。

文章系列
Part 1: Rendering, Directives, and Events
Part 2: Components, Props, and Slots (待翻譯)
Part 3: Vue-cli (待翻譯)
Part 4: Vuex (待翻譯)
Part 5: Animations (待翻譯)
Vue 吸取并融合了其它框架的成功之處,并且它的代碼非常簡潔,這是我非常喜歡它的一個原因。比如下面這些特點:
- 虛擬的 DOM 和靈活的組件,提供了一種 View 層優(yōu)先,props ,并且類似于 React 的 Redux 式的存儲方式。
- 類似于 Angular 的條件渲染和數(shù)據(jù)綁定方式。
- 在簡單性和性能方面,受到 Polymer 的啟發(fā),Vue 采用了相同的 HTML 代碼,styles 樣式和 JavaScript 代碼書寫方式。
還有其它的一些相對于它的對手的優(yōu)點,也讓我覺得欣喜:更干凈,更語義化的 API 文檔,相比 React 更好的表現(xiàn),和 Polymer 一樣不采用 polyfills,并且是一個獨立而又不像 Angular 那樣固執(zhí)己見的 MVVM 框架。
接下來我們繼續(xù),或許你親自去閱讀他們社區(qū)的與其他框架的比較會更好。它很值得一讀,如果你更愿意去書寫代碼的話,那么你可以跳過它。
讓我們開始吧!
讓我們從 "Hello,world!" 開始。按照下面這樣做你就可以開始了:
<div id="app">
{{ text }} Nice to meet Vue.
</div>
new Vue({
el: '#app',
data: {
text: 'Hello World!'
}
});
DEMO
如果你對 React 很了解的話,這種寫法你也一定覺得很熟悉。通過 JavaScript 創(chuàng)建變量,用雙大括號模板引用變量,不同的使 Vue 直接采用 Html,而 React 采用JSX語法。JSX 語法很容易上手,但是
Vue 不用把 class 轉(zhuǎn)化為 className 等簡潔的寫法,讓我真的很喜歡它。你可能也注意到Vue非常的輕量,運行起來也很迅速。
接下來我們一起嘗試下Vue的一些令人喜愛的特性:循環(huán)和條件渲染。
條件渲染
我創(chuàng)建了一個items對象,類似導(dǎo)航,以便我知道我可以重用它。把它定義為一個數(shù)組可能更有意義,方便以后動態(tài)地更改。如果按照原生的 JS 寫法可能會是這樣的:創(chuàng)建數(shù)組,然后創(chuàng)建空的字符串對象,再把數(shù)組的每個條目嵌套上 <li> 標(biāo)簽,最后在外面嵌套 <ul> 標(biāo)簽,最后使用 innerHTML 方法操作 DOM:
<div id="container"></div>
const items = [
'thingie',
'another thingie',
'lots of stuff',
'yadda yadda'
];
function listOfStuff() {
let full_list = '';
for (let i = 0; i < items.length; i++) {
full_list = full_list + `<li> ${items[i]} </li>`
}
const contain = document.querySelector('#container');
contain.innerHTML = `<ul> ${full_list} </ul>`;
}
listOfStuff();
DEMO
沒問題,但是有點凌亂。現(xiàn)在讓我們用
Vue 的循環(huán)v-for實現(xiàn)同樣的效果:
<div id="app">
<ul>
<li v-for="item in items">
{{ item }}
</li>
</ul>
</div>
const app4 = new Vue({
el: '#app',
data: {
items: [
'thingie',
'another thingie',
'lots of stuff',
'yadda yadda'
]
}
});
非常的簡單明了。如果你了解 Angular,這種寫法對你來說肯定很熟悉。這樣的條件渲染方式非常的簡單,清晰。如果你還在用傳統(tǒng)的原生 JS 而且也在尋求改變,那么你可以很容易上手 Vue。
另外一個非常好用的指令是v-model,它可以動態(tài)綁定數(shù)據(jù)。像這樣:
<div id="app">
<h3>Type here:</h3>
<textarea v-model="message" class="message" rows="5" maxlength="72"></textarea><br>
<p class="booktext">{{ message }} </p>
</div>
new Vue({
el: '#app',
data() {
return {
message: 'This is a good place to type things.'
}
}
});
通過上面的例子,你可能注意到兩點。首先,頁面沒有進(jìn)行任何 DOM 操作,就能夠動態(tài)的更新顯示的文本內(nèi)容。Vue 能夠通過 v-model 指令在 <textarea> 和 <p> 標(biāo)簽之間創(chuàng)建雙向的數(shù)據(jù)綁定,來實現(xiàn)頁面展示數(shù)據(jù)的動態(tài)變換。另外一點,我們把數(shù)據(jù)存放在函數(shù)里面,沒有調(diào)用這個函數(shù),它自己就工作了。像以前的例子一樣,我們也可以把它放在一個對象內(nèi)部。但是它只會在 Vue 實例或者完全相同的應(yīng)用下工作。Vue 實例可以引用它,并且所有的子組件也可以獲取它的數(shù)據(jù)。把數(shù)據(jù)存儲在函數(shù)里面是一個很好的做法,因為當(dāng)我們開始使用組件并且還想讓各組件保持各自的狀態(tài),我們就可以采取這種存儲方式。
這些并不是唯一的簡單的輸入綁定,v-if可以切換,v-show顯示或隱藏 DOM 。
這兒有更多的指令可供你參考。
事件處理
數(shù)據(jù)綁定確實不錯,但是沒有事件的處理我們什么也做不了,所以我們跳過它,開始講事件處理!這一部分也是我非常喜愛的部分。我們將通過綁定和監(jiān)聽器的去監(jiān)聽 DOM 事件。
new Vue({
el: '#app',
data() {
return {
counter: 0
}
},
methods: {
increment() {
this.counter++;
}
}
});
<div id="app">
<p><button @click="increment">+</button> {{ counter }}</p>
</div>
我們創(chuàng)建了一個方法叫做increment,并且我們可以看到它自動綁定了this,然后引用了此實例中的數(shù)據(jù)和組件。不需要我們手動去操作。
Methods并不是唯一創(chuàng)建自定義函數(shù)的方式,你還可以通過watch方法。兩種方式的不同之處主要在于methods適合小的同步計算,而watch則更有助于處理多任務(wù)的,異步的,消耗資源的不斷更新數(shù)據(jù)的操作。我經(jīng)常會用watch去實現(xiàn)動畫效果。
讓我們再深入一點,看看如何傳遞事件病進(jìn)行一些動態(tài)的樣式綁定。如果你還記得上面表格的內(nèi)容,你可以使用快捷寫法:代替v-bind,接下來我們可以通過:style或者:class方式很容易的綁定樣式并且傳遞狀態(tài)。像這樣的綁定方式還有很多。
在下面的例子里面,我們采用hsl()方法——是通過對色相(H)、飽和度(S)、明度(L)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的方法。當(dāng)我們的鼠標(biāo)在屏幕上運動時,指針在屏幕上的位置就會發(fā)生變化,背景風(fēng)格將得到相應(yīng)的更新。在這里我們使用了ES6的模版字面量。
<div id="app" :style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }" @mousemove="xCoordinate">
<p><button @click="increment">+</button> {{ counter }} <button @click="decrement">-</button></p>
<p>Pixels across: {{ x }}</p>
</div>
new Vue({
el: '#app',
data() {
return {
counter: 0,
x: 0
}
},
methods: {
increment() {
this.counter++;
},
decrement() {
this.counter--;
},
xCoordinate(e) {
this.x = e.clientX;
}
}
});
DEMO
可以看到我們甚至不需要將事件傳遞給@click處理程序,Vue 就可以自動把它作為方法的參數(shù)傳遞。
當(dāng)然了,原生的方法也可以做到,比如說event.clientX,并且和this實例結(jié)合起來會更簡單。在下面的例子你將看到 Vue 操作起來是多么的簡單和語義化。
我們甚至不需要創(chuàng)建方法,我們只需在組件內(nèi)部的行內(nèi)樣式里添加操作就足夠了:
<div id="app">
<div class="item">

<div class="quantity">
<button class="inc" @click="counter > 0 ? counter -= 1 : 0">-</button>
<span class="quant-text">Quantity: {{ counter }}</span>
<button class="inc" @click="counter += 1">+</button>
</div>
<button class="submit" @click="">Submit</button>
</div><!--item-->
</div>
new Vue({
el: '#app',
data() {
return {
counter: 0
}
}
});
DEMO
你可以看到我們更新狀態(tài)是直接通過@click處理程序而沒有使用函數(shù)方法,還可以添加一些簡單邏輯處理。但是一旦你的邏輯變得過于復(fù)雜,這樣的做法就會讓代碼的可讀性變的很差,這時候你就可以考慮把它放在一個函數(shù)方法內(nèi)部,通過method來存儲,無論如何這將會是一個好的選擇。
文章系列:
Part 1: Rendering, Directives, and Events
Part 2: Components, Props, and Slots (待翻譯)
Part 3: Vue-cli (待翻譯)
Part 4: Vuex (待翻譯)
Part 5: Animations (待翻譯)
注釋:原文作者:Sarah Drasner,本文已得到作者授權(quán)。