DAY15 | 跟 Vue.js 認識的30天 - Vue 動態模組(Dynamic Components)

這次寫的內容是之前都沒使用過的,所以就盡量讓自己有概念,希望之後能使用到。

使用 v-bind:is 來切換模組

切換模組的基本語法

1
<component :is="currentComponent"></component>

currentComponent 是用來決定目前使用的模組是哪一個。

透過全域註冊來設定模組

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<button v-for="tab of tabs" :key="tab" @click="currentTabComponent = tab">{{ tab }}</button>
<component :is="currentTabComponent"></component>
<script>
Vue.component('home',{
template:`<div>I am home!</div>`
})
Vue.component('shop',{
template:`<div>I am shop!</div>`
})
Vue.component('rate',{
template:`<div>I am rate!</div>`
})
const vm = new Vue({
el:'#vm',
data:{
tabs:['home','shop','rate'],
// 指定當前欲顯示的模組'名'
currentTabComponent:'home'
}
})
</script>

data 中設定的 currentTabComponent 為當前欲顯示的模組, currentTabComponent 值為模組名,並透過 <component :is="currentTabComponent"></component> 中的 Attribute is 綁定 currentTabComponent ,指定顯示的模組內容。

透過在 data 設定物件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<button v-for="tab of tabs" :key="tab.name" @click="currentTabComponent = tab">{{ tab.name }}</button>
<component :is="currentTabComponent"></component>
<script>
const tabs = [{
name: 'home',
template: `<div>I am home!</div>`
},
{
name: 'shop',
template: `<div>I am shop!</div>`
},
{
name: 'rate',
template: `<div>I am rate!</div>`
}]

const vm = new Vue({
el:'#vm',
data:{
tabs: tabs,
// 指定當前欲顯示的模組 '物件'
currentTabComponent: tabs[0]
}
})
</script>

透過物件處理模組的資料(如模組名及模板),並且 currentTabComponent 的值為模組資料,而非模組名。

使用 <keep-alive> 建立動態模組緩存

在一般情況下,Vue 是透過建立新的模組,來執行模組的切換(動態模組),但這樣一來,當我們在 A 模組點選或寫下東西後,切換到 B 模組,在執行別的事情後,再返回 A 模組,會發現原本在 A 模組點選或寫下的東西都會消失(回復成初始的模組狀態)。

這樣的情況可以透過 <keep-alive> 來解決, <keep-alive> 主要是用來將沒使用到的模組緩存起來(就是將模組最後一次出現的狀態儲存起來),也因此在切換的過程中,模組的狀態不會因為切換而消失。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<button v-for="tab of tabsC" :key="tab" @click="keepAliveComponent=tab">{{tab}}</button>
<!--<keep-alive>用來包裹欲被緩存的模組-->
<keep-alive>
<component :is="keepAliveComponent"></component>
</keep-alive>
<script>
Vue.component("A", {
template: `<div>I am A!</div>`
});
Vue.component("B", {
template: `<div>I am B!</div>`
});
Vue.component("C", {
template: `<div>I am C!</div>`
});

Vue.component("posts", {
template: `<div>
<button v-for="title of titles" :key="title" @click="currentPostComponent=title">{{title}}</button>
<component :is="currentPostComponent"></component>
</div>`,
data() {
return {
titles: ["A", "B", "C"],
currentPostComponent:'A'
};
}
});

Vue.component("archives", {
template: `<div>
<input type="text">
</div>`
});

const vm = new Vue({
el: "#vm",
data: {
tabs: ["posts", "archives"],
keepAliveComponent: "posts"
}
});
</script>

<keep-alive> 屬性 includeexclude

  • v-bind:include="/reg/" :值為正規表達式,只有符合該值的模組才能被緩存。

  • include="string" :值為字符串,只有符合該值的模組才能被緩存。

  • v-bind:exclude="/reg/" :值為字符串或正規表達式,只有符合該值的模組才能被緩存。

  • exclude="string" :值為字符串或正規表達式,只有符合該值的模組才能被緩存。

提醒:如果值為字符串的話,就不需使用 v-bind 來綁定了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<button v-for="tab of tabsC" :key="tab" @click="keepAliveComponent=tab">{{tab}}</button>
<!--只有 posts 模組才能被緩存-->
<!--所以 archives 模組寫下文字,切換模組之後,該文字不會被緩存起來-->
<keep-alive :include="posts">
<component :is="keepAliveComponent"></component>
</keep-alive>
<script>
Vue.component("A", {
template: `<div>I am A!</div>`
});
Vue.component("B", {
template: `<div>I am B!</div>`
});
Vue.component("C", {
template: `<div>I am C!</div>`
});

Vue.component("posts", {
template: `<div>
<button v-for="title of titles" :key="title" @click="currentPostComponent=title">{{title}}</button>
<component :is="currentPostComponent"></component>
</div>`,
data() {
return {
titles: ["A", "B", "C"],
currentPostComponent:'A'
};
}
});

Vue.component("archives", {
template: `<div>
<input type="text">
</div>`
});

const vm = new Vue({
el: "#vm",
data: {
tabs: ["posts", "archives"],
keepAliveComponent: "posts"
}
});
</script>

因為對於異步模組的部分研究的還不夠,看起來還可以加上 webpack 的使用,但對於 webpack 的研究也還不夠,所以這一塊就先不寫出來了!

Demo:

See the Pen DAY15 | 跟 Vue.js 認識的30天 - Vue 動態模組(Dynamic Components) by Celeste6666 (@celeste6666) on CodePen.

參考資料:

Vue.js - 动态组件 & 异步组件

Vue.js -keep-alive