vue 之 动态组件(动态组件-生命周期,&异步组件-懒加载)
一.动态组件
原理:
过程一: 每次进行组件间的切换时,Vue都创建了一个新的组件实例,同时存在销毁过程
过程二:为了避免过程一每次进行销毁重建的问题,那么可以通过 keep-alive 来处理
语法:
1 | <component v-bind: is = "currentTabComponent" ></component> |
过程一 案例:
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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> |
过程二 案例改进
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 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> |
动态组件生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <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> |
二.异步组件
第一步:如何实现懒加载
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 | <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> |
第二步:定义一个工厂函数
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 | <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> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现