Vue 系列一 之 Vue 基礎
Create by jsliang on 2018-11-8 13:34:30
Recently revised in 2019-1-12 19:23:17
Hello 小夥伴們,如果覺得本文還不錯,記得給個 star , 你們的 star 是我學習的動力!GitHub 地址
推薦通過 目錄
以及使用 返回目錄
按鈕,獲得更好的閱讀體驗。
一 目錄
不折騰的前端,和鹹魚有什麼區別~
二 正文
飲水思源:Vue 官方文件
Vue (讀音 /vjuː/,類似於 view) 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合。另一方面,當與現代化的工具鏈以及各種支援類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動。
學習版本:v2.5.21
編寫時間:2019-1-10
如版本更迭太大或者時間小夥伴們看到這篇文章太久沒更新,小夥伴們請檢視 Vue 官方文件學習最新的 Vue。
2.1 初識 Vue
那麼,Vue 是怎麼折騰的呢?
話不多說,我們直接來看程式碼實現:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: '#app',
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<div>
<p>Hello World</p>
</div>
`
})
</script>
</body>
</html>
複製程式碼
現在,我們解析下程式碼執行:
- 首先,建立一個空白的 html 模板檔案,通過 CDN 引用 Vue:
Vue 一般分兩個版本:
開發版本:開發中有友好的錯誤提示。
生產版本:上線部署使用的版本,程式碼包比較小
index.html 程式碼片段
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
複製程式碼
- 然後,我們編寫一個掛載點,即我們的 Vue,最終會在哪個 DOM 裡面進行操作:
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
複製程式碼
- 最後,我們通過 New 一個 Vue 例項物件,對我們 id 為
app
的 DOM 節點進行操作:
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容。
// 最外層必須有一層包裹,例如 <div>
template: `
<div>
<p>Hello World</p>
</div>
`
})
複製程式碼
這樣,我們最終就顯示了 Vue 的簡單引用,是不是覺得非常簡單:
2.2 掛載資料 - data
如果 Vue 僅僅是隻有 template
這個模板裝載,那麼它跟 jQuery 就顯得沒多大差別了,下面我們使用下 Vue 的 data
進行資料渲染:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: '#app',
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<div>
<p>{{ text }}</p>
</div>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
text: 'Hello World!'
}
}
})
</script>
</body>
</html>
複製程式碼
在這裡,我們可以看到,我們在 template
中加了一個 <p>
標籤,通過 {{ text }}
形式,引入了一個叫 text
的 data
資料:
<p>{{ text }}</p>
複製程式碼
接著我們在 <scirpt>
中定義了 text
的內容,從而實現資料渲染:
data() {
return {
// template 中要使用的資料
text: 'Hello World!'
}
}
複製程式碼
這樣,我們就知道了,我們不僅可以通過模板 template
來渲染 <div>
標籤,我們也可以將 js 中定義的資料或者變數,通過操作 data
從而改變 html 裡面的內容。
2.3 進一步優化 el
在 2.1
章節 及 2.2
章節中,我們使用 el
的方式是:
el: '#app',
複製程式碼
該 el
掛載形式,在 Vue 內部執行機制中,它會根據你傳入的值,進行查詢:
- 如果傳入的是
#app
,那它就判斷查詢id
為app
的節點; - 如果傳入的是
.app
,那它就查詢class
為app
的節點; - 如果傳入的是節點名
div
,那它就查詢節點名……
大家應該清楚,這樣判斷查詢是需要時間的,多執行一個判斷都是罪惡。
所以我們可以:
el: document.getElementById('app'),
複製程式碼
這般操作,使得 Vue 直接將掛載點掛載到 id
上去,從而獲得更好的載入速度。這算是對 el
的一個小優化。
2.4 插值表示式 - {{ }}
如果小夥伴有點印象,應該還記得,我們在章節 2.2
中通過 {{}}
這個插值表示式的使用,在 data
中對其裡面的資料進行操作。
下面,我們進一步講解這個插值表示式 {{}}
還可以進行哪種騷操作:
- 物件:{{ {name: 'jack'} }}
- 字串 {{ 'Hello World!' }}
- 布林值: {{ isTrue == -1 }}
- 三元表示式: {{ isTrue ? '正確' : '錯誤' }}
光字面理解是不夠的,我們通過程式碼進行操作演示:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<div>
<p>{{ text }}</p>
<p>{{ {name: 'jack'} }}</p>
<p>{{ 'Hello World!' }}</p>
<p>{{ isTrue == -1 }}</p>
<p>{{ isTrue ? '真' : '假' }}</p>
</div>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
text: 'Hello World!',
isTrue: true
}
}
})
</script>
</body>
</html>
複製程式碼
它在瀏覽器的展示為:
關鍵程式碼講解:
<div>
<!-- 賦值 text 到 <p> 標籤中 -->
<p>{{ text }}</p>
<!-- 賦值物件到標籤中 -->
<p>{{ {name: 'jack'} }}</p>
<!-- 直接賦值字串到標籤中 -->
<p>{{ 'Hello World!' }}</p>
<!--
直接進行布林判斷,isTrue 在 data 中設定為 true,
而 -1 轉為 布林值 是 false,所以兩者不相等
輸出值為 false
-->
<p>{{ isTrue == -1 }}</p>
<!-- 執行三元表示式,isTrue 為 true,輸出 真 -->
<p>{{ isTrue ? '真' : '假' }}</p>
</div>
複製程式碼
通過三元表示式的運用,我們可以做到一些判斷:陣列最後一個元素、是否動態顯示隱藏等。
2.5 指令 - v-*
在 Vue 中,如果單單使用 {{}}
這種插值表示式,是滿足不了我們對資料的操作慾望的。所以,Vue 以 v-if
、v-bind
等形式,提供了一些對於頁面 + 資料的更為方便的操作:指令
v-text
v-html
v-if
v-else-if
v-else
v-show
v-bind
v-click
v-model
v-for
這裡採用一個頁面展示所有指令,如果小夥伴想逐個詳細瞭解指令,推薦去官網檢視學習:Vue 指令
那麼,上面的指令都是怎麼使用的呢?這裡通過一個 index.html
及一張圖向大家演示其基本用法:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
<style>
/* 顏色樣式:紅、綠、藍 */
.color-red {
color: red;
}
.color-blue {
color: blue;
}
.color-green {
color: green;
}
</style>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<div>
<p>v-text 演示</p>
<p v-text='vTextOrHtml'></p>
<br/>
<p>v-html 演示</p>
<p v-html='vTextOrHtml'></p>
<br/>
<p>v-if -> v-else-if -> v-else 演示</p>
<p v-if='vIf == 1'>Hello v-If</p>
<p v-else-if='vIf == 2'>Hello v-else-if</p>
<p v-else>Hello v-else</p>
<br/>
<p>v-show 演示</p>
<p v-show='isTrue'></p>
<br/>
<p>v-bind:××× -> :××× 演示</p>
<input v-bind:value="vBind" v-bind:class="colorRed" type="text"/>
<input v-bind:other1="other1" :other2="other2" :other3=" 'other3' " value="Hello :屬性值" type="text"/><br/>
<br/>
<p>v-click -> @click 演示</p>
<button v-on:click=" vBind= 'Hello v-on:click' ">v-on:click - 點選直接改變 vBind 的值</button><br>
<button @click="changevBindValue">v-on:click - 點選通過事件改變 vBind 的值</button><br>
<br/>
<p>v-model 演示</p>
<input v-model="vModel" type="text" />
<p>{{ vModel }}</p>
<br/>
<p>v-for 演示</p>
<ul v-for="(item, index) in vFor" :class="item.classStyle">
<li>{{index+1}}. {{item.name}} - {{item.age}}</li>
</ul>
</div>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
// v-text 及 v-html 使用資料
vTextOrHtml: '<span style="color: red">我是紅的</p>',
// v-if 使用資料
vIf: 2,
// v-show 使用資料
isTrue: false,
// v-bind 使用資料
vBind: "Hello v-bind",
// v-bind 通過動態繫結 class 修改樣式
colorRed: 'color-red',
// v-bind 的 :屬性 的使用形式
other1: 'other1',
// 同上
other2: 'other2',
// v-model 使用資料
vModel: 'Hello v-model',
// v-for 使用資料
vFor: [{
name: '張三', // 姓名
age: 22, // 年齡
classStyle: "color-red" // 樣式
},
{
name: '李四',
age: 23,
classStyle: "color-blue"
},
{
name: '王五',
age: 24,
classStyle: "color-green"
}
]
}
}
})
</script>
</body>
</html>
複製程式碼
我們看下頁面:
在這裡,我們對程式碼進行下講解:
<div>
<!--
1. v-html
這裡直接將 vTextOrHtml 中的文字
當成 string 渲染到頁面中去
-->
<p v-text='vTextOrHtml'></p>
<br/>
<!--
2. v-html
這裡在渲染 vTextOrHtml 的過程中,
如果遇到標籤,則對標籤頁進行渲染
-->
<p v-html='vTextOrHtml'></p>
<br/>
<!--
3. v-if/v-else-if/v-if
判斷 data 中 vIf 的值是多少,
這裡有三種情況:v-if、v-else-if、v-else。
如果專案中有更多情況,則再新增 v-else-if 即可
-->
<p v-if='vIf == 1'>Hello v-If</p>
<p v-else-if='vIf == 2'>Hello v-else-if</p>
<p v-else>Hello v-else</p>
<br/>
<!--
4. v-show
判斷 isTrue 是真還是假,
它不同於 v-if 的方面是:
v-if 如果是假,則在 Element 中沒有渲染
v-show 如果是假,則該標籤為 display: none
-->
<p v-show='isTrue'></p>
<br/>
<!--
5. v-bind
v-bind 有兩種格式:
1. v-bind:value - 全寫
2. :value - 簡寫
我們還可以通過 v-bind:class 來動態賦值
v-bind:other1="other1" 在頁面中顯示就是:
<input other1="other1" />>
-->
<input v-bind:value="vBind" v-bind:class="colorRed" type="text"/>
<input v-bind:other1="other1" :other2="other2" :other3=" 'other3' " value="Hello :屬性值" type="text"/><br/>
<br/>
<!--
6. v-on
v-on:click 有兩種格式:
1. v-on:click - 全寫
2. @click - 簡寫
v-on:click 除了可以直接在裡面寫表示式,還可以填寫方法
-->
<button v-on:click=" vBind= 'Hello v-on:click' ">v-on:click - 點選直接改變 vBind 的值</button><br>
<button @click="changevBindValue">v-on:click - 點選通過事件改變 vBind 的值</button><br>
<br/>
<!--
7. v-model
v-model 是雙向資料繫結,
在這裡,上面 input 的修改
會影響到下面 p 顯示的內容
-->
<input v-model="vModel" type="text" />
<p>{{ vModel }}</p>
<br/>
<!--
8. v-for
v-for 迴圈體遍歷輸出
-->
<ul v-for="(item, index) in vFor" :class="item.classStyle">
<li>{{index+1}}. {{item.name}} - {{item.age}}</li>
</ul>
</div>
複製程式碼
v-bind 和 v-model 的區別:
- v-bind:將 Vue 中的資料同步到頁面,即該值大部分用於前端向瀏覽器傳固定資料。v-bind 可以給任何屬性賦值,是從 Vue 到頁面的單向資料流,即 Vue -> html。
- v-model:雙向資料繫結,前端向瀏覽器傳資料,使用者操作瀏覽器的更改前端可以察覺到。v-model 只能給具有 value 屬性的元素進行雙向資料繫結(必須使用的是有 value 屬性的元素),即 Vue -> html -> Vue
關於 Vue 的指令,這裡咱先對它進行了個全面的簡單瞭解,知道它是如何使用的。
想詳細學習的小夥伴,記得前往官方文件:Vue 文件
2.6 事件 - methods
在上一章 2.5
中,我們通過在 button
中使用 v-on:click
時,給它綁定了事件方法。
但是,在 2.5
中,我們大體講述了事件方法的使用,但是我們只是一知半解。
在這裡,我們抽取出來做下講解:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<button @click="addStyle">新增行內樣式</button>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
}
},
// 6. methods - 方法,即我們的頁面事件
// 可以理解為在 jQuery 中定義 Function
methods: {
addStyle(e) {
e.toElement.style.background = "red"
}
}
})
</script>
</body>
</html>
複製程式碼
此時頁面的點選效果如下所示:
此刻我們分析下頁面:
- 首先,在上面的
<button>
中,我們通過@click
綁定了事件addStyle
:
<button @click="addStyle">新增行內樣式</button>
複製程式碼
- 接著,方法的編寫,需要寫到與
data
同級的methods
中:
methods: { // 方法
addStyle: function(e) {
e.toElement.style.background = "red"
}
}
複製程式碼
- 然後,我們通過傳遞引數
e
,可以獲取到點選的時候的元素,通過查詢,我們發現它的樣式所在的目錄結構如下:
- button
- toElement
- style
- background
複製程式碼
- 最後,我們在使用者點選按鈕的時候,直接修改了它的背景。
2.7 元件 - components
敲黑板!敲黑板!敲黑板!
元件是 Vue 學習的重點,元件化的 SPA 或者 SSR 頁面的製作,使得我們開發起來更加隨心應手。
2.7.1 初始元件
在上面的章節中,我們一直使用 template: ``
的形式,編寫 html
標籤。但是,隨著專案的不斷擴大,如果全部程式碼都寫在一個 template
中,那麼我們修改起來就複雜了。所以,我們應該想辦法對它進行劃分,例如將一個頁面劃分為 header
、content
、footer
三部分。這樣,我們需要修改 nav
的時候,只需要在 header
中修改就可以了。
頁面結構
- app
- header
- content
- footer
複製程式碼
這樣的思想,在 Vue
中體現為元件(組合起來的部件)。那麼,在 Vue
中,需要如何做,才能比較好的做到元件的劃分呢?
首先,我們捋捋邏輯:
在前面的章節中,在 Vue 的定義上,我們將首個 template
掛載到了 id 為 app
的節點上。然後將 template
劃分為三個塊:header
、content
、footer
。
在這裡,我們將
#app
的template
叫做父元件,header
等叫子元件,就好比父親下面有三個兒子一樣。
然後,我們嘗試從 new Vue
中抽離單個元件出來:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 宣告入口元件
var App = {
template: `<h1>我是入口元件</h1>`
}
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: '<app/>',
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
}
},
// 6. methods - 方法,即我們的頁面事件
// 可以理解為在 jQuery 中定義 Function
methods: {
},
// 7. components - 元件名稱
components: {
// key 是元件名,value 是元件物件
app: App
}
})
</script>
</body>
</html>
複製程式碼
這時候頁面如下所示:
接著,我們分析下進行的三部曲:
- 在
component
中定義並抽離App
- 在
new Vue
外定義App
- 在
template
中使用App
這樣,我們就做到了單個元件的抽離,及 new Vue
是 App
的父元件,App
是 new Vue
的子元件。
最後,既然上面做到了單個元件的抽離,現在我們實現多個元件的抽離:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue學習</title>
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 宣告頭部元件
var MyHeader = {
template: `<div>我是頭部</div>`
};
// 宣告內容元件
var MyContent = {
template: `<div>我是軀體</div>`
};
// 宣告底部元件
var myFooter = {
template: `<div>我是底部</div>`
}
new Vue({
el: document.getElementById('app'),
components: { // 宣告要用的元件們
// key 是元件名,value 是元件物件
'my-header': MyHeader,
'my-content': MyContent,
'my-footer': myFooter
},
template: `
<div>
<my-header/>
<my-content/>
<my-footer/>
</div>
`
})
</script>
</body>
</html>
複製程式碼
這樣,我們就做到了元件的抽離。
注意:template
有且只有一個根節點,如果沒有根節點,Vue 會給你報錯。
template: `
<my-header/>
<my-content/>
<my-footer/>
`
複製程式碼
上面那種寫法是錯誤的,謹記。
做到這裡,我們又可以愉快玩耍了,而且 myHeader
、myContent
、myFooter
中是可以跟 new Vue
一樣寫 data
、methods
的哦~
例如:
var MyHeader = {
data() {
return {
// ... 定義資料
}
},
template: `<h1>我是頭部</h1>`,
methods: {
// 定義方法
}
};
複製程式碼
2.7.2 父子元件通訊
既然前面章節已經劃分了父子元件,那麼在這裡,我們講件更有趣的事:父子元件通訊。
在元件間,我們 new Vue
相當於父親(父元件),他有自己的 data
。然後,子元件也會有自己的 data
。
- 假如某天,父親找到自己的兒子,想告訴他:
“其實你不是我親生的,你的姓名是***”
。
那麼,在 Vue
中,我們要怎麼做,才能讓它的兒子(子元件),知道它的姓究竟是什麼呢?我們來看程式碼:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 子元件
var Son = {
template: `
<div>我的名字:{{name}}</div>
`,
props: ['name']
}
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<son :name="name"></son>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
name: '皮皮蝦'
}
},
// 6. methods - 方法,即我們的頁面事件
// 可以理解為在 jQuery 中定義 Function
methods: {
},
// 7. components - 元件名稱
components: {
// key 是元件名,value 是元件物件
son: Son
}
})
</script>
</body>
</html>
複製程式碼
編寫完程式碼後,我們可以在瀏覽器看到,瀏覽器顯示出了:我的名字:皮皮蝦
,這幾個大字。
哦了,原來父親的兒子姓 皮
。同時,我們也就知道了,在父元件中的資料,通過 v-bind:***
的形式,將父元件中的 data
,傳送給子元件。而子元件呢,通過 props
的定義,獲取到了父親的資料。
這樣我們就做到了父元件傳遞資料給子元件。
2.7.3 共用元件
在上面中,我們提到:
- App
- my-header
- my-content
- my-footer
複製程式碼
在 App
這個元件上,我們掛載了三個子元件:myHeader
、myContent
、myFooter
。
- 但是,如果某天,出現了一個女孩(共有元件),這個女孩的名字叫:
beautifulGirl
。然後不僅三個兒子(子元件)想追求她,就連父親(父元件)也想追求她(夠瘋狂)。
那麼,在 Vue
中,是通過什麼方式,使父親和兒子都有機會接觸到這個女孩呢?(父子元件如何能夠都可以使用共用元件)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 宣告頭部元件
var MyHeader = {
template: `
<div>我是頭部,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 宣告內容元件
var MyContent = {
template: `
<div>我是內容區,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 宣告底部元件
var myFooter = {
template: `
<div>我是底部,我想了解<beautiful-girl></beautiful-girl></div>
`
}
// 宣告共用元件
Vue.component('beautiful-girl', {
template: `<span>—— 美麗女孩 ——</span>`
})
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<div>
<my-header/>
<my-content/>
<my-footer/>
</div>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
}
},
// 6. methods - 方法,即我們的頁面事件
// 可以理解為在 jQuery 中定義 Function
methods: {
},
// 7. components - 元件名稱
components: {
// key 是元件名,value 是元件物件
'my-header': MyHeader,
'my-content': MyContent,
'my-footer': myFooter,
}
})
</script>
</body>
</html>
複製程式碼
在這裡,我們通過 Vue.component('元件名',{ })
的形式,註冊了個全域性元件 beautiful-girl
,這樣,父子元件都可以直接呼叫該元件,從而在瀏覽器顯示為:
現在,父親和兒子都可以和漂亮女孩溝通了。究竟是父親給他們的兒子找了個後媽,還是他們兒子找到自己所愛呢?敬請期待……
2.8 過濾器 - filter
在工作中,我們經常需要對一些後端傳回來的資料進行過濾。例如:我司 Java 小哥傳回來的金錢,就是分進位制的,即:1元 = 100分。所以傳回個 2000,其實是 20 元。那麼,在 Vue 中,我們該如何對資料進行過濾呢?
2.8.1 區域性過濾
話不多說,先上程式碼:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 宣告頭部元件
var MyHeader = {
template: `
<div>我是頭部,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 宣告內容元件
var MyContent = {
template: `
<div>我是內容區,我想了解<beautiful-girl></beautiful-girl></div>
`
};
// 宣告底部元件
var myFooter = {
template: `
<div>我是底部,我想了解<beautiful-girl></beautiful-girl></div>
`
}
// 宣告共用元件
Vue.component('beautiful-girl', {
template: `<span>—— 美麗女孩 ——</span>`
})
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<p>我是錢多多,我有 {{money}} 多一點: ¥{{money | addDot}},跟我混有出息~</p>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
money: 1000000
}
},
// 6. methods - 方法,即我們的頁面事件
// 可以理解為在 jQuery 中定義 Function
methods: {
},
// 7. components - 元件名稱
components: {
// key 是元件名,value 是元件物件
},
// 8. filters - 元件內的過濾器
filters: {
addDot(money) {
return (money / 1000000 + ".000000");
}
}
})
</script>
</body>
</html>
複製程式碼
在上面,我們通過 filters
中的 addDot
方法,對資料進行了過濾,將 money
的資料,從 10000000
變成了 1.000000
。
2.8.2 全域性過濾
然後,在嘗試了局部 filters
的好處之後,我們還可以試試它的全域性過濾器寫法:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 學習</title>
</head>
<body>
<!-- 2. Vue 掛載點 - Vue 的虛擬 DOM 在這裡操作到實際渲染 -->
<!-- 簡單理解為 jQuery 的拼接字串(並不全是) -->
<div id="app"></div>
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服務 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<!-- Vue Router CDN - 管理路由 -->
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.js"></script>
<!-- Axios CDN - 呼叫介面 -->
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
// 全域性過濾器
Vue.filter('addDot', function(money) {
return (money / 1000000 + ".000000");
})
new Vue({
// 3. el - 掛載目標,即渲染在哪個掛載點
el: document.getElementById('app'),
// 4. template - 模板,即渲染到掛載點的內容
// 最外層必須有一層包裹,例如 <div>
template: `
<p>我是錢多多,我有 {{money}} 多一點: ¥{{money | addDot}},跟我混有出息~</p>
`,
// 5. data - 資料,即在操作中需要用到的資料
// 可以理解為在 jQuery 中 var text = "Hello World!"
// {{ text }} 為資料渲染到 DOM 的方式之一
data() {
return {
// template 中要使用的資料
money: 1000000
}
},
// 6. methods - 方法,即我們的頁面事件
// 可以理解為在 jQuery 中定義 Function
methods: {
},
// 7. components - 元件名稱
components: {
// key 是元件名,value 是元件物件
},
// 8. filters - 元件內的過濾器
filters: {
}
})
</script>
</body>
</html>
複製程式碼
最後在頁面中顯示為: