1. 前言
本小節我們將介紹 Vue 的動態組件,以及緩存 keep-alive 的使用。包括動態組件的使用方法,以及如何使用 keep-alive 實現組件的緩存效果。
2. 慕課解釋
動態組件是讓多個組件使用同一個掛載點,并動態切換。動態組件是 Vue 的一個高級用法,但其實它的使用非常簡單。keep-alive 是 vue 的內置組件,能在組件切換過程中將狀態保存在內存中,防止重復渲染 DOM。
3. 動態組件如何使用
通過使用保留的 <component>
元素,動態地把組件名稱綁定到它的 is
特性,可以實現動態組件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<component :is="currentView"></component>
<button @click="changeView('A')">切換到A</button>
<button @click="changeView('B')">切換到B</button>
<button @click="changeView('C')">切換到C</button>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('ComponentA', {
template: '<div> 組件 A </div>',
})
Vue.component('ComponentB', {
template: '<div> 組件 B </div>',
})
Vue.component('ComponentC', {
template: '<div> 組件 C </div>',
})
var vm = new Vue({
el: '#app',
data() {
return {
currentView: 'ComponentB'
}
},
methods: {
changeView(name) {
this.currentView = `Component${name}`
}
}
})
</script>
</html>
代碼解釋:
HTML 代碼第 2 行,我們使用動態組件 component,將當前需要展示的組件名通過變量 currentView 綁定到 component 的 is 屬性上。
HTML 代碼第 3-5 行,我們定義了三個按鈕,通過點擊按鈕切換 currentView 的值。
JS 代碼第 3-11 行,我們定義了組件 ComponentA、ComponentB、ComponentC。
最終的實現效果是:當點擊按鈕的時候會動態切換展示的組件。
4. keep-alive
keep-alive
是 Vue
提供的一個抽象組件,用來對組件進行緩存,從而節省性能,由于是一個抽象組件,所以在頁面渲染完畢后不會被渲染成一個 DOM 元素。被 keep-alive
緩存的組件只有在初次渲染時才會被創建,并且當組件切換時不會被銷毀。
4.1. 基礎用法
keep-alive
的用法相對簡單,直接使用 keep-alive
包裹需要緩存的組件即可:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<keep-alive>
<component :is="currentView"></component>
</keep-alive>
<button @click="changeView('A')">切換到A</button>
<button @click="changeView('B')">切換到B</button>
<button @click="changeView('C')">切換到C</button>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('ComponentA', {
template: '<div> 組件 A </div>',
created() {
console.log('組件A created')
}
})
Vue.component('ComponentB', {
template: '<div> 組件 B </div>',
created() {
console.log('組件B created')
}
})
Vue.component('ComponentC', {
template: '<div> 組件 C </div>',
created() {
console.log('組件C created')
}
})
var vm = new Vue({
el: '#app',
data() {
return {
currentView: 'ComponentB'
}
},
methods: {
changeView(name) {
this.currentView = `Component${name}`
}
}
})
</script>
</html>
代碼解釋:
HTML 代碼第 2-3 行,我們使用 keep-alive 包裹動態組件 component,將當前需要展示的組件名通過變量 currentView 綁定到 component 的 is 屬性上。
HTML 代碼第 5-7 行,我們定義了三個按鈕,通過點擊按鈕切換 currentView 的值。
JS 代碼第 3-29 行,我們定義了組件 ComponentA、ComponentB、ComponentC,分別定義了他們的 created 和 beforeDestroy 事件。
之前我們介紹過,keep-alive
緩存的組件只有在初次渲染時才會被創建。所以,我們通過修改 currentView 切換組件時,組件的 beforeDestroy 事件不會觸發。若該組件是第一次渲染,會觸發 created 事件,當再次切換顯示該組件時,created 事件不會再次觸發。
4.2. activated 和 deactivated 生命周期
activated 和 deactivated 和我們之前學習的生命周期函數一樣,也是組件的生命周期函數。不過, activated
和 deactivated
只在 <keep-alive>
內的所有嵌套組件中觸發。activated
:進入組件時觸發。deactivated
:退出組件時觸發。
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<keep-alive>
<component :is="currentView"></component>
</keep-alive>
<button @click="changeView('A')">切換到A</button>
<button @click="changeView('B')">切換到B</button>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('ComponentA', {
template: '<div> 組件 A </div>',
activated() {
console.log('組件A 被添加')
},
deactivated() {
console.log('組件A 被移除')
}
})
Vue.component('ComponentB', {
template: '<div> 組件 B </div>',
activated() {
console.log('組件B 被添加')
},
deactivated() {
console.log('組件B 被移除')
}
})
var vm = new Vue({
el: '#app',
data() {
return {
currentView: 'ComponentB'
}
},
methods: {
changeView(name) {
this.currentView = `Component${name}`
}
}
})
</script>
</html>
代碼解釋:
JS 代碼中,我們定義了組件 ComponentA、ComponentB,并分別定義了他們的 activated 和 deactivated 事件函數。
HTML 代碼第 2-3 行,我們使用 keep-alive 包裹動態組件 component,將當前需要展示的組件名通過變量 currentView 綁定到 component 的 is 屬性上。
HTML 代碼第 5-6 行,我們定義了兩個按鈕,通過點擊按鈕切換 currentView 的值。當我們切換組件顯示時,可以看到這樣的打印信息:
1. ComponentA -> ComponentB 會打印出:組件A 被移除、組件B 被添加
2. ComponentB -> ComponentA 會打印出:組件B 被移除、組件A 被添加
TIPS: 注意,activated 和 deactivated 這兩個生命周期函數一定是要在使用了 keep-alive 組件后才會有的,否則不存在。
4.3. include 和 exclude
include
和 exclude
是 keep-alive 的兩個屬性,允許組件有條件地緩存。
include: 可以是字符串或正則表達式,用來表示只有名稱匹配的組件會被緩存。
exclude: 可以是字符串或正則表達式,用來表示名稱匹配的組件不會被緩存。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<keep-alive include="ComponentA,ComponentB">
<component :is="currentView"></component>
</keep-alive>
<button @click="changeView('A')">切換到A</button>
<button @click="changeView('B')">切換到B</button>
<button @click="changeView('C')">切換到C</button>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('ComponentA', {
template: '<div> 組件 A </div>',
created() {
console.log('組件A created')
},
activated() {
console.log('組件A 被添加')
},
deactivated() {
console.log('組件A 被移除')
}
})
Vue.component('ComponentB', {
template: '<div> 組件 B </div>',
created() {
console.log('組件B created')
},
activated() {
console.log('組件B 被添加')
},
deactivated() {
console.log('組件B 被移除')
}
})
Vue.component('ComponentC', {
template: '<div> 組件 C </div>',
created() {
console.log('組件C created')
},
activated() {
console.log('組件C 被添加')
},
deactivated() {
console.log('組件C 被移除')
}
})
var vm = new Vue({
el: '#app',
data() {
return {
currentView: 'ComponentB'
}
},
methods: {
changeView(name) {
this.currentView = `Component${name}`
}
}
})
</script>
</html>
代碼解釋:
HTML 代碼第 2-4 行,我們使用 keep-alive 包裹動態組件 component。給 keep-alive 指定需要緩存組件 ComponentA,ComponentB。
在之前的小節我們了解到 keep-alive
緩存的組件只有在初次渲染時才會被創建。所以,在案例中,組件 ComponentA 和 ComponentB 的 created 函數只有在第一次組件被創建的時候才會觸發,而 ComponentC 的 created 函數當每次組件顯示的時候都會觸發。
exclude 示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<keep-alive exclude="ComponentA,ComponentB">
<component :is="currentView"></component>
</keep-alive>
<button @click="changeView('A')">切換到A</button>
<button @click="changeView('B')">切換到B</button>
<button @click="changeView('C')">切換到C</button>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('ComponentA', {
template: '<div> 組件 A </div>',
created() {
console.log('組件A created')
}
})
Vue.component('ComponentB', {
template: '<div> 組件 B </div>',
created() {
console.log('組件B created')
}
})
Vue.component('ComponentC', {
template: '<div> 組件 C </div>',
created() {
console.log('組件C created')
}
})
var vm = new Vue({
el: '#app',
data() {
return {
currentView: 'ComponentB'
}
},
methods: {
changeView(name) {
this.currentView = `Component${name}`
}
}
})
</script>
</html>
代碼解釋:
HTML 代碼第 2-4 行,我們使用 keep-alive 包裹動態組件 component。給 keep-alive 指定不需要緩存組件 ComponentA,ComponentB。
5. 小結
本節,我們帶大家學習了動態組件和緩存組件在項目中的運用。主要知識點有以下幾點:
- 使用
<component :is="component-name"/>
的方式實現動態組件; - 使用 keep-alive 實現組件的緩存;
- 使用 include 屬性指定需要緩存的組件;
- 使用 exclude 屬性指定不需要緩存的組件。