介紹
Vue.js 是什么
Vue.js(讀音 /vju?/,類似于 view) 是一套構(gòu)建用戶界面的漸進式框架。與其他重量級框架不同的是鸯屿,Vue 采用自底向上增量開發(fā)的設(shè)計止潮。Vue 的核心庫只關(guān)注視圖層,它不僅易于上手吴汪,還便于與第三方庫或既有項目整合惠窄。另一方面,當(dāng)與單文件組件和 Vue 生態(tài)系統(tǒng)支持的庫結(jié)合使用時漾橙,Vue 也完全能夠為復(fù)雜的單頁應(yīng)用程序提供驅(qū)動杆融。
如果你是有經(jīng)驗的前端開發(fā)者,想知道 Vue.js 與其它庫/框架的區(qū)別霜运,查看對比其它框架脾歇。
起步
官方指南假設(shè)你已有 HTML蒋腮、CSS 和 JavaScript 中級前端知識。如果你剛開始學(xué)習(xí)前端開發(fā)藕各,將框架作為你的第一步可能不是最好的主意——掌握好基礎(chǔ)知識再來池摧!之前有其他框架的使用經(jīng)驗對于學(xué)習(xí) Vue.js 是有幫助的,但這不是必需的激况。
嘗試 Vue.js 最簡單的方法是使用 JSFiddle Hello World 例子作彤。你可以在瀏覽器新標(biāo)簽頁中打開它,跟著例子學(xué)習(xí)一些基礎(chǔ)用法乌逐〗呋洌或者你也可以創(chuàng)建一個 .html
文件<a>,然后通過如下方式引入 Vue:</a>
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/vue"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
你可以查看安裝教程來了解其他安裝 Vue 的選項浙踢。請注意我們不推薦新手直接使用 vue-cli
绢慢,尤其是對 Node.js 構(gòu)建工具不夠了解的同學(xué)。
聲明式渲染
Vue.js 的核心是一個允許采用簡潔的模板語法來聲明式的將數(shù)據(jù)渲染進 DOM:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app"</span>></span></div>
<div class="line"> {{ message }}</div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="keyword">var</span> app = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">message</span>: <span class="string">'Hello Vue!'</span></div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app" class="demo">Hello Vue!</div>
<script>var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } })</script>
我們已經(jīng)生成了我們的第一個 Vue 應(yīng)用成黄!看起來這跟單單渲染一個字符串模板非常類似呐芥,但是 Vue 在背后做了大量工作。現(xiàn)在數(shù)據(jù)和 DOM 已經(jīng)被綁定在一起奋岁,所有的元素都是響應(yīng)式的思瘟。我們?nèi)绾沃溃看蜷_你的瀏覽器的控制臺(就在這個頁面打開)闻伶,并修改 app.message
滨攻,你將看到上例相應(yīng)地更新。
除了文本插值蓝翰,我們還可以采用這樣的方式綁定 DOM 元素屬性:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app-2"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">v-bind:title</span>=<span class="string">"message"</span>></span></div>
<div class="line"> 鼠標(biāo)懸停幾秒鐘查看此處動態(tài)綁定的提示信息光绕!</div>
<div class="line"> <span class="tag"></<span class="name">span</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="keyword">var</span> app2 = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app-2'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">message</span>: <span class="string">'頁面加載于 '</span> + <span class="keyword">new</span> <span class="built_in">Date</span>()</div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app-2" class="demo"><span title="頁面加載于 Tue Jul 04 2017 17:14:24 GMT+0800 (中國標(biāo)準(zhǔn)時間)">鼠標(biāo)懸停幾秒鐘查看此處動態(tài)綁定的提示信息!</span></div>
<script>var app2 = new Vue({ el: '#app-2', data: { message: '頁面加載于 ' + new Date() } })</script>
這里我們遇到點新東西畜份。你看到的 v-bind
屬性被稱為指令诞帐。指令帶有前綴 v-
,以表示它們是 Vue 提供的特殊屬性爆雹⊥=叮可能你已經(jīng)猜到了,它們會在渲染的 DOM 上應(yīng)用特殊的響應(yīng)式行為钙态。簡言之慧起,這里該指令的作用是:“將這個元素節(jié)點的 title
屬性和 Vue 實例的 message
屬性保持一致”。
再次打開瀏覽器的 JavaScript 控制臺輸入 app2.message = '新消息'
册倒,就會再一次看到這個綁定了 title
屬性的 HTML 已經(jīng)進行了更新蚓挤。
條件與循環(huán)
控制切換一個元素的顯示也相當(dāng)簡單:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app-3"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">p</span> <span class="attr">v-if</span>=<span class="string">"seen"</span>></span>現(xiàn)在你看到我了<span class="tag"></<span class="name">p</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="keyword">var</span> app3 = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app-3'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">seen</span>: <span class="literal">true</span></div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app-3" class="demo"><span>現(xiàn)在你看到我了</span></div>
<script>var app3 = new Vue({ el: '#app-3', data: { seen: true } })</script>
繼續(xù)在控制臺設(shè)置 app3.seen = false
,你會發(fā)現(xiàn) “現(xiàn)在你看到我了” 消失了。
這個例子演示了我們不僅可以綁定 DOM 文本到數(shù)據(jù)灿意,也可以綁定 DOM 結(jié)構(gòu)到數(shù)據(jù)估灿。而且,Vue 也提供一個強大的過渡效果系統(tǒng)脾歧,可以在 Vue 插入/更新/刪除元素時自動應(yīng)用過渡效果甲捏。
還有其它很多指令,每個都有特殊的功能鞭执。例如司顿,v-for
指令可以綁定數(shù)組的數(shù)據(jù)來渲染一個項目列表:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app-4"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">ol</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">"todo in todos"</span>></span></div>
<div class="line"> {{ todo.text }}</div>
<div class="line"> <span class="tag"></<span class="name">li</span>></span></div>
<div class="line"> <span class="tag"></<span class="name">ol</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="keyword">var</span> app4 = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app-4'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">todos</span>: [</div>
<div class="line"> { <span class="attr">text</span>: <span class="string">'學(xué)習(xí) JavaScript'</span> },</div>
<div class="line"> { <span class="attr">text</span>: <span class="string">'學(xué)習(xí) Vue'</span> },</div>
<div class="line"> { <span class="attr">text</span>: <span class="string">'整個牛項目'</span> }</div>
<div class="line"> ]</div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app-4" class="demo">
- 學(xué)習(xí) JavaScript
- 學(xué)習(xí) Vue
- 整個牛項目
</div>
<script>var app4 = new Vue({ el: '#app-4', data: { todos: [ { text: '學(xué)習(xí) JavaScript' }, { text: '學(xué)習(xí) Vue' }, { text: '整個牛項目' } ] } })</script>
在控制臺里,輸入 app4.todos.push({ text: '新項目' })
兄纺,你會發(fā)現(xiàn)列表中添加了一個新項大溜。
處理用戶輸入
為了讓用戶和你的應(yīng)用進行互動,我們可以用 v-on
指令綁定一個事件監(jiān)聽器估脆,通過它調(diào)用我們 Vue 實例中定義的方法:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app-5"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">p</span>></span>{{ message }}<span class="tag"></<span class="name">p</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">button</span> <span class="attr">v-on:click</span>=<span class="string">"reverseMessage"</span>></span>逆轉(zhuǎn)消息<span class="tag"></<span class="name">button</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="keyword">var</span> app5 = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app-5'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">message</span>: <span class="string">'Hello Vue.js!'</span></div>
<div class="line"> },</div>
<div class="line"> <span class="attr">methods</span>: {</div>
<div class="line"> <span class="attr">reverseMessage</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span> {</div>
<div class="line"> <span class="keyword">this</span>.message = <span class="keyword">this</span>.message.split(<span class="string">''</span>).reverse().join(<span class="string">''</span>)</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app-5" class="demo">
Hello Vue.js!
<button>逆轉(zhuǎn)消息</button></div>
<script>var app5 = new Vue({ el: '#app-5', data: { message: 'Hello Vue.js!' }, methods: { reverseMessage: function () { this.message = this.message.split('').reverse().join('') } } })</script>
注意在 reverseMessage
方法中钦奋,我們更新了應(yīng)用的狀態(tài),但沒有觸碰 DOM——所有的 DOM 操作都由 Vue 來處理疙赠,你編寫的代碼不需要關(guān)注底層邏輯付材。
Vue 還提供了 v-model
指令,它能輕松實現(xiàn)表單輸入和應(yīng)用狀態(tài)之間的雙向綁定圃阳。
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app-6"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">p</span>></span>{{ message }}<span class="tag"></<span class="name">p</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">v-model</span>=<span class="string">"message"</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="keyword">var</span> app6 = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app-6'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">message</span>: <span class="string">'Hello Vue!'</span></div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app-6" class="demo">
Hello Vue!
<input></div>
<script>var app6 = new Vue({ el: '#app-6', data: { message: 'Hello Vue!' } })</script>
組件化應(yīng)用構(gòu)建
組件系統(tǒng)是 Vue 的另一個重要概念厌衔,因為它是一種抽象,允許我們使用小型捍岳、自包含和通掣皇伲可復(fù)用的組件構(gòu)建大型應(yīng)用。仔細想想锣夹,幾乎任意類型的應(yīng)用界面都可以抽象為一個組件樹:

在 Vue 里页徐,一個組件本質(zhì)上是一個擁有預(yù)定義選項的一個 Vue 實例,在 Vue 中注冊組件很簡單:
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="comment">// 定義名為 todo-item 的新組件</span></div>
<div class="line">Vue.component(<span class="string">'todo-item'</span>, {</div>
<div class="line"> <span class="attr">template</span>: <span class="string">'<li>這是個待辦項</li>'</span></div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
現(xiàn)在你可以用它構(gòu)建另一個組件模板:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">ol</span>></span></div>
<div class="line"> <span class="comment"><!-- 創(chuàng)建一個 todo-item 組件的實例 --></span></div>
<div class="line"> <span class="tag"><<span class="name">todo-item</span>></span><span class="tag"></<span class="name">todo-item</span>></span></div>
<div class="line"><span class="tag"></<span class="name">ol</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
但是這樣會為每個待辦項渲染同樣的文本银萍,這看起來并不炫酷变勇,我們應(yīng)該能將數(shù)據(jù)從父作用域傳到子組件。讓我們來修改一下組件的定義贴唇,使之能夠接受一個屬性:
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line">Vue.component(<span class="string">'todo-item'</span>, {</div>
<div class="line"> <span class="comment">// todo-item 組件現(xiàn)在接受一個</span></div>
<div class="line"> <span class="comment">// "prop"贰锁,類似于一個自定義屬性</span></div>
<div class="line"> <span class="comment">// 這個屬性名為 todo。</span></div>
<div class="line"> props: [<span class="string">'todo'</span>],</div>
<div class="line"> <span class="attr">template</span>: <span class="string">'<li>{{ todo.text }}</li>'</span></div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
現(xiàn)在滤蝠,我們可以使用 `v-bind` 指令將待辦項傳到每一個重復(fù)的組件中:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app-7"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">ol</span>></span></div>
<div class="line"> <span class="comment"><!--</span></div>
<div class="line"> 現(xiàn)在我們?yōu)槊總€ todo-item 提供待辦項對象</div>
<div class="line"> 待辦項對象是變量,即其內(nèi)容可以是動態(tài)的授嘀。</div>
<div class="line"> 我們也需要為每個組件提供一個“key”物咳,晚些時候我們會做個解釋。</div>
<div class="line"> --></div>
<div class="line"> <span class="tag"><<span class="name">todo-item</span></span></div>
<div class="line"> <span class="attr">v-for</span>=<span class="string">"item in groceryList"</span></div>
<div class="line"> <span class="attr">v-bind:todo</span>=<span class="string">"item"</span></div>
<div class="line"> <span class="attr">v-bind:key</span>=<span class="string">"item.id"</span>></div>
<div class="line"> <span class="tag"></<span class="name">todo-item</span>></span></div>
<div class="line"> <span class="tag"></<span class="name">ol</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<figure class="highlight js">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line">Vue.component(<span class="string">'todo-item'</span>, {</div>
<div class="line"> <span class="attr">props</span>: [<span class="string">'todo'</span>],</div>
<div class="line"> <span class="attr">template</span>: <span class="string">'<li>{{ todo.text }}</li>'</span></div>
<div class="line">})</div>
<div class="line"><span class="keyword">var</span> app7 = <span class="keyword">new</span> Vue({</div>
<div class="line"> <span class="attr">el</span>: <span class="string">'#app-7'</span>,</div>
<div class="line"> <span class="attr">data</span>: {</div>
<div class="line"> <span class="attr">groceryList</span>: [</div>
<div class="line"> { <span class="attr">id</span>: <span class="number">0</span>, <span class="attr">text</span>: <span class="string">'蔬菜'</span> },</div>
<div class="line"> { <span class="attr">id</span>: <span class="number">1</span>, <span class="attr">text</span>: <span class="string">'奶酪'</span> },</div>
<div class="line"> { <span class="attr">id</span>: <span class="number">2</span>, <span class="attr">text</span>: <span class="string">'隨便其他什么人吃的東西'</span> }</div>
<div class="line"> ]</div>
<div class="line"> }</div>
<div class="line">})</div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
<div id="app-7" class="demo">
1. 蔬菜
2. 奶酪
3. 隨便其他什么人吃的東西
</div>
<script>Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '奶酪' }, { id: 2, text: '隨便其他什么人吃的東西' } ] } })</script>
這只是一個假設(shè)的例子蹄皱,但是我們已經(jīng)設(shè)法將應(yīng)用分割成了兩個更小的單元览闰,子單元通過 props
接口實現(xiàn)了與父單元很好的解耦芯肤。我們現(xiàn)在可以進一步為我們的 todo-item
組件實現(xiàn)更復(fù)雜的模板和邏輯的改進,而不會影響到父單元压鉴。
在一個大型應(yīng)用中崖咨,有必要將整個應(yīng)用程序劃分為組件,以使開發(fā)可管理油吭。在后續(xù)教程中我們將詳述組件击蹲,不過這里有一個(假想的)使用了組件的應(yīng)用模板是什么樣的例子:
<figure class="highlight html">
<table>
<tbody>
<tr>
<td class="code">
<pre>
<div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"app"</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">app-nav</span>></span><span class="tag"></<span class="name">app-nav</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">app-view</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">app-sidebar</span>></span><span class="tag"></<span class="name">app-sidebar</span>></span></div>
<div class="line"> <span class="tag"><<span class="name">app-content</span>></span><span class="tag"></<span class="name">app-content</span>></span></div>
<div class="line"> <span class="tag"></<span class="name">app-view</span>></span></div>
<div class="line"><span class="tag"></<span class="name">div</span>></span></div>
</pre>
</td>
</tr>
</tbody>
</table>
</figure>
與自定義元素的關(guān)系
你可能已經(jīng)注意到 Vue 組件非常類似于自定義元素——它是 Web 組件規(guī)范的一部分,這是因為 Vue 的組件語法部分參考了該規(guī)范婉宰。例如 Vue 組件實現(xiàn)了 Slot API 與 is
特性歌豺。但是,還是有幾個關(guān)鍵差別:
Web 組件規(guī)范仍然處于草案階段心包,并且尚無瀏覽器原生實現(xiàn)类咧。相比之下,Vue 組件不需要任何補丁蟹腾,并且在所有支持的瀏覽器(IE9 及更高版本)之下表現(xiàn)一致痕惋。必要時,Vue 組件也可以包裝于原生自定義元素之內(nèi)娃殖。
Vue 組件提供了純自定義元素所不具備的一些重要功能值戳,最突出的是跨組件數(shù)據(jù)流,自定義事件通信以及構(gòu)建工具集成珊随。
準(zhǔn)備好了嗎述寡?
我們剛才簡單介紹了 Vue 核心最基本的功能——本教程的其余部分將涵蓋這些功能以及其他高級功能更詳細的細節(jié),所以請務(wù)必讀完整個教程叶洞!
<div class="guide-links"><span>← 安裝</span> <span style="float:right">Vue 實例 →</span></div>
<div class="footer">發(fā)現(xiàn)錯誤鲫凶?想?yún)⑴c編輯? 在 Github 上編輯此頁衩辟!</div>
</div>