一.动态组件
原理:
过程一: 每次进行组件间的切换时,Vue都创建了一个新的组件实例,同时存在销毁过程
过程二:为了避免过程一每次进行销毁重建的问题,那么可以通过 keep-alive 来处理
语法:
<component v-bind:is="currentTabComponent"></component>
过程一 案例:
App.vue <template> <div> <div id="dynamic-component-demo" class="demo"> <button v-for="tab in tabs" v-bind:key="tab" v-bind:class="['tab-button', { active: currentTab === tab }]" v-on:click="currentTab = tab" > {{ tab }} </button> <component v-bind:is="currentTab" class="tab"></component> </div> <!-- <button @click="myName = 'my-header'">显示 my-header</button> <button @click="myName = 'my-footer'">显示 my-footer</button> --> </div> </template> <script> import MyHeader from "./components/MyHeader.vue"; import MyFooter from "./components/MyFooter.vue"; import MyMain from "./components/MyMain.vue"; export default { data() { return { currentTab: "my-header", tabs: ["my-header", "my-main", "my-footer"], }; }, components: { MyHeader, MyMain, MyFooter, }, methods: {}, mounted() {}, created() {}, }; </script> <style> .tab-button { padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid #ccc; cursor: pointer; background: #f0f0f0; margin-bottom: -1px; margin-right: -1px; } .tab-button:hover { background: #e0e0e0; } .tab-button.active { background: #e0e0e0; } .tab { border: 1px solid #ccc; padding: 10px; } </style>
MyMain.vue
<template>
<div>
<div>main</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
created() {
console.log("my-main组件重新生成了");
},
beforeDestroy() {
console.log("my-main组件被销毁了");
},
};
</script>
<style></style>
过程二 案例改进
App.vue <template> <div> <div id="dynamic-component-demo" class="demo"> <button v-for="tab in tabs" v-bind:key="tab" v-bind:class="['tab-button', { active: currentTab === tab }]" v-on:click="currentTab = tab" > {{ tab }} </button> <keep-alive> <component v-bind:is="currentTab" class="tab"></component> </keep-alive> </div> <!-- <button @click="myName = 'my-header'">显示 my-header</button> <button @click="myName = 'my-footer'">显示 my-footer</button> --> </div> </template> <script> import MyHeader from "./components/MyHeader.vue"; import MyFooter from "./components/MyFooter.vue"; import MyMain from "./components/MyMain.vue"; export default { data() { return { currentTab: "my-header", tabs: ["my-header", "my-main", "my-footer"], }; }, components: { MyHeader, MyMain, MyFooter, }, methods: {}, mounted() {}, created() {}, }; </script> <style> .tab-button { padding: 6px 10px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid #ccc; cursor: pointer; background: #f0f0f0; margin-bottom: -1px; margin-right: -1px; } .tab-button:hover { background: #e0e0e0; } .tab-button.active { background: #e0e0e0; } .tab { border: 1px solid #ccc; padding: 10px; } </style>
动态组件生命周期
<template> <div> <div>header {{ num }}</div> </div> </template> <script> export default { data() { return { num: 0, }; }, created() {}, activated() { this.num = localStorage.getItem("num"); }, deactivated() { console.log('销毁了') }, }; </script> <style></style>
二.异步组件
第一步:如何实现懒加载
<template>
<div>
<h1>Vue中异步组件的使用</h1>
<button @click="handleClick">按钮</button>
<div v-if="isShow">
<List />
</div>
</div>
</template>
<script>
// import List from "./components/List.vue";
export default {
data() {
return {
isShow: false,
};
},
components: {
List: () => import(/* webpackChunName:"list" */ "./components/List.vue"),
},
methods: {
handleClick() {
this.isShow = !this.isShow;
},
},
};
</script>
<style>
div {
text-align: center;
}
</style>
第二步:定义一个工厂函数
<template>
<div>
<h1>Vue中异步组件的使用</h1>
<button @click="handleClick">按钮</button>
<div v-if="isShow">
<AsyncList />
</div>
</div>
</template>
<script>
// import List from "./components/List.vue";
import LoadingComponent from "./components/LoadingComponent.vue";
import ErrorComponent from "./components/ErrorComponent.vue";
//工厂函数
const AsyncList = () => ({
component: import("./components/List.vue"),
loading: LoadingComponent,
error: ErrorComponent,
delay: 200, //延迟200毫秒
timeout: 1, //超时
});
export default {
data() {
return {
isShow: false,
};
},
components: {
AsyncList,
},
methods: {
handleClick() {
this.isShow = !this.isShow;
},
},
};
</script>
<style>
div {
text-align: center;
}
</style>