Vue03 10.組件化編程 10.1基本說明 官網鏈接:https://v2.cn.vuejs.org/v2/guide/components-registration.html 在大型應用開發時,頁面可以劃分成很多部分。不同的頁面,往往也會有相同的部分——例如可能會有相同的頭部導航 如果每個頁面 ...
Vue03
10.組件化編程
10.1基本說明
官網鏈接:https://v2.cn.vuejs.org/v2/guide/components-registration.html
-
在大型應用開發時,頁面可以劃分成很多部分。不同的頁面,往往也會有相同的部分——例如可能會有相同的頭部導航
-
如果每個頁面都獨自開發,無疑增加了我們的開發成本。因此,我們會把頁面的不同部分拆分成獨立的組件,然後在不同的頁面共用這些組件,避免重覆開發
- 組件(Component)是Vue.js最強大的功能之一(組件提高了復用性:界面復用性和代碼復用性)
- 組件也是一個Vue實例,也包括:data,methods,生命周期函數等
- 組件渲染需要html模板,所以增加了template屬性,屬性的值就是HTML模板
- 對於全局組件,任何Vue實例都可以直接在HTML中通過組件名稱來使用該組件
- data在組件中是一個函數,不再是一個對象,這樣每次引用組件都是獨立的對象/數據
10.2應用實例
為什麼需要組件化編程?
例子
現在希望實現一個功能:點擊一個按鈕,可以顯示點擊的次數。如果要求多個按鈕都實現該功能呢?
10.2.1非組件化方式
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>組件化編程-普通方式</title>
</head>
<body>
<div id="app">
<!--非組件化方式-普通方式-->
<button v-on:click="count++">點擊次數={{count}}次[非組件化方式]</button><br/>
<!--
1.如果需要多個按鈕都實現同樣的功能,直接粘貼複製是不可行的,
因為這樣的話按鈕都綁定了同一個數據count,
當其中一個按鈕按下,其他按鈕顯示的數據也會跟著改變。
2.我們現在的要求是:不同的按鈕的數據應該分開計算,又該怎麼實現?--可以在數據池中增加不同的屬性
-->
<button v-on:click="count2 ++">點擊次數={{count2}}次[非組件化方式]</button><br/>
<!--3.但是新的問題又出現了,當又要增加多個同樣功能的按鈕時,怎麼實現呢?
仍然像之前一樣,在數據池中不停地增加新的屬性嗎?-->
<button v-on:click="count3 ++">點擊次數={{count3}}次[非組件化方式]</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: "#app",
data: {//data數據池
count: 0,
count2: 0,
count3: 0
}
})
</script>
</body>
</html>
如上所述,多個按鈕的界面和業務功能都是類似的,但是我們都重新寫了一次,代碼復用性差,如果是在複雜的案例中,問題將會更加明顯。解決方案就是——組件化編程。
10.2.2全局組件方式
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>組件化編程-全局組件</title>
</head>
<body>
<div id="app">
<h1>組件化-全局組件</h1>
<!--使用全局組件-->
<!--vue解析時,會用模板template來替換這個"counter"標識-->
<counter></counter><br/>
<counter></counter><br/>
<counter></counter>
</div>
<script src="vue.js"></script>
<script>
// 1.定義一個全局組件,名為 counter
// 2.{} 表示的就是 組件相關的內容
// 3.template 用於指定該組件的界面,因為會引用到數據池的數據,所以使用模板字元串
// 4.註意:要把組件視為Vue實例,也有自己的數據池和 方法 methods
// 5.對於組件,我們的數據池數據是使用函數/方法返回的(目的是為了保證每一個組件的數據是獨立的!),不能使用原來的方式
// 6.這時我們就實現了 界面通過template實現共用,業務處理可以復用 的目的
// 7.全局組件是屬於所有的vue實例的,因此可以在任何一個vue實例中使用:
// 例如當前頁面中有一個vue實例,如果我們再聲明幾個vue實例,該全局組件都可以在這些vue實例中使用
Vue.component("counter", {
//組件渲染需要html模板,所以增加了template屬性,值就是HTML模板
template: `<button v-on:click="click()">點擊次數={{count}}次[全局組件化方式]</button>`,
data() {//註意和原來的方式不一樣
return {count: 0}
},
methods: {//方法可以共用,但data數據不能共用
click() {
this.count++;//每一個組件的this對象不同,因此同一個方法改變的是不同的count
}
}
})
//創建vue實例,必須有
let vm = new Vue({
el: "#app"
})
</script>
</body>
</html>
![image-20230109191402803](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20230109191402803.png)
10.2.3局部組件方式
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>組件化編程-局部組件</title>
</head>
<body>
<div id="app">
<h1>組件化-局部組件</h1>
<!--使用局部組件,該組件是從 被掛載到 div(id=app)的vue實例中來的-->
<my_counter></my_counter><br/>
<my_counter></my_counter><br/>
<my_counter></my_counter>
</div>
<script src="vue.js"></script>
<script>
//定義一個組件 buttonCounter
// 可以把常用的組件定義在js文件中(export),如果某個頁面需要使用,直接import引入即可
const buttonCounter = {
template: `<button v-on:click="click()">點擊次數={{count}}次[局部組件化方式]</button>`,
data() {
return {count: 0}
},
methods: {
click() {
this.count++;
}
}
}
//創建vue實例,必須有
let vm = new Vue({
el: "#app",
components: {//引入某個組件,此時該組件就是一個局部組件,該組件的使用範圍只在當前的vue實例中
"my_counter":buttonCounter
}
})
// 如果新創建了一個vue實例,掛載到一個div中(id="app2"),在該div中如果要使用局部組件
// 也必須在該vue實例中引入該組件,否則div((id="app2")無法使用該局部組件
</script>
</body>
</html>
![image-20230109192706442](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20230109192706442.png)
10.2.4全局組件VS局部組件
-
全局組件是屬於所有的vue實例的,因此可以在任何一個vue實例中使用。
例如當前頁面中有一個vue實例,如果我們再聲明幾個vue實例,該全局組件都可以在這些vue實例中使用
-
局部組件的使用範圍只在當前的vue實例中。
例如:如果新創建了一個vue實例,掛載到一個新的div中(如:id="app2"),在div中如果要使用局部組件,也必須在新的vue實例中引入該組件,否則該div中無法使用該局部組件
-
組件定義需要放在new Vue()前,否則組件引入/註冊會失效
10.3組件化小結
- 組件也是一個Vue實例,它的定義也包括:data,methods,生命周期函數等
- data在組件中是一個函數,不再是一個對象,這樣每次引用組件都是獨立的對象
- 組件渲染需要html模板,所以增加了template屬性,屬性的值就是HTML模板
11.生命周期和鉤子函數
官網:https://v2.cn.vuejs.org/v2/guide/instance.html
11.1基本說明
- Vue實例有一個完整的生命周期,也就是說從開始創建、初始化數據、編譯模板、掛載DOM、渲染-更新-渲染、卸載等一系列過程,我們稱之為Vue實例的生命周期
- 鉤子函數(監聽函數/生命周期函數):Vue實例在完整的生命周期過程中(比如設置數據監聽,編譯模板,將實例掛載到DOM,在數據變化時更新DOM等),會自動觸發鉤子函數
- 鉤子函數的作用:在某個階段,給程式員一個做某些處理的機會
11.2Vue實例的生命周期
-
new Vue()
創建了一個Vue的實例對象,此時就會進入組件的創建過程
-
Init Events & Lifecycle
初始化組件的事件和生命周期函數
-
beforeCreate
組件創建之後遇到的第一個生命周期函數,這個階段data和methods以及dom結構都未被初始化,也就是獲取不到data的值,不能調用methods中的方法
-
Init injections & reactivity
這個階段中,正在初始化data和methods中的方法
-
created
這個階段組件的data和methods中的方法已經初始化結束,可以訪問,但是dom結構未初始化,頁面未渲染
此階段適合發起ajax請求,因為模板的數據未渲染
-
編譯模板結構(在記憶體中)
-
beforeMount
當模板在記憶體中編譯完成,此時記憶體中的模板結構還未渲染至頁面上,看不到真實的數據
-
Create vm.$el and replace 'el' with it
在把記憶體中渲染好的模板結構替換至真實的dom結構,也就是頁面上
-
mounted
此時頁面渲染好,用戶看到的是真實的頁面數據,生命周期創建階段完畢,進入到了運行中的階段
-
生命周期運行中
1)beforeUpdate:當執行此函數,數據池的數據是新的,但頁面是舊的
2)Virtual DOM re-render and patch:根據最新的data數據,重新渲染記憶體中的模板結構,並把渲染好的模 板結構替換至頁面
3)updated:頁面已經完成了更新,此時data數據和頁面的數據都是新的
-
beforeDestroy
當執行此函數時,組件即將被銷毀,但是還沒有真正開始銷毀,此時組件的data,methods方法還可以被調用
-
Teardown
註銷組件和事件監聽
-
destroyed
組件已經完成了銷毀
![](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/Vue%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.png)
11.3應用實例
需求:展示Vue實例的生命周期和鉤子函數執行時機
- 重點研究幾個重要的鉤子函數(監聽函數/生命周期函數):beforeCreate,created,beforeMount,mounted,beforeUpdate,updated
- 在這幾個鉤子函數中,數據模型是否載入/使用?自定義方法是否載入/可用?html模板是否載入/使用?html模板是否完成渲染?