vue 组件动态切换和非动态切换的演示
首页组件:
<template> <div> <div class="tab-wrap"> <div :class="{tab:true,active:item.active}" v-for="(item,index) in tabs" :key="index" @click="tabsSelect(index,item.componentName)">{{item.title}}</div> <!--<div class="tab">会员登录</div>--> <!--<div class="tab">菜品分类</div>--> </div> <!--非动态方式--> <!--<details-component v-if="this.currentComponent==='details-component'"></details-component>--> <!--<log-in-component v-if="this.currentComponent==='log-in-component'"></log-in-component>--> <!--<sort-component v-if="this.currentComponent==='sort-component'"></sort-component>--> <!--动态方式 component为固定写法--> <!--因为vue在切换的时候数据都会重新渲染,所以再切回去的时候就会清空--> <!--避免重新渲染,可以用缓存keep-alive--> <keep-alive> <component :is="currentComponent"></component> </keep-alive> </div> </template> <script> import DetailsComponent from "@/pages/test/components/DetailsComponent"; import LogInComponent from "@/pages/test/components/LogInComponent"; import SortComponent from "@/pages/test/components/SortComponent"; export default { name: "good", components: { DetailsComponent, //菜单详情 LogInComponent, //会员登录 SortComponent //商品分类 }, data() { return { tabs:[ {title:'菜单详情',active:true,componentName:'details-component'}, {title:'会员登录',active:false,componentName:'log-in-component'}, {title:'菜品分类',active:false,componentName:'sort-component'}, ], currentComponent:'details-component' //默认 } }, methods: { tabsSelect(index,componentName){ for (let i = 0; i < this.tabs.length; i++) { if (this.tabs[i].active){ this.tabs[i].active = false; break; } } this.tabs[index].active = true; //解决数据发生变化视图不渲染问题 this.$set(this.tabs,index,this.tabs[index]); //让获取的组件赋值给this.currentComponent 然后再去判断 this.currentComponent = componentName; console.log(this.currentComponent) } }, } </script> <style scoped> .tab-wrap { width: 100%; } .tab-wrap .tab { display: inline-block; padding: 5px 10px; border: 1px solid white; margin-right: 5px; } .tab-wrap .tab.active { background-color: #007aff; } </style>
子组件:SortComponent.vue
<template> <div> <div class="main"> <div :class="{'classify-tab':true,active:item.active}" v-for="(item,index) in classify" :key="item.id" @click="classifySelect(index)"> {{ item.title }} </div> <!-- <div class="classify-tab">馒头片</div>--> <!-- <div class="classify-tab">啤酒</div>--> </div> </div> </template> <script> export default { name: "SortComponent", data() { return { //点击切换颜色 经典写法 classify: [ {id: 1, title: '羊肉串', active: false}, {id: 2, title: '馒头片', active: true}, {id: 3, title: '啤酒', active: false}, ] } }, methods:{ classifySelect(index){ for (let i = 0; i <this.classify.length; i++) { //关闭 if(this.classify[i].active){ //当循环到点击的位置时,不需要再循环下面的,然后跳出就行,可以节省资源 this.classify[i].active=false break; } } this.classify[index].active = true; //this,$set解决数据更新视图不渲染问题 this.$set(this.classify,index,this.classify[index]); } } } </script> <style scoped> .main { border: 1px solid #EFEFEF; padding: 5px 10px; } .main .classify-tab { display: inline-block; padding: 5px 10px; border: 1px solid white; margin-right: 5px; } .main .classify-tab.active { background-color: #b7cae3; } </style>
子组件:LogInComponent.vue
<template> <div> <div class="main"> <input type="text"> <button type="button">会员登录</button> </div> </div> </template> <script> export default { name: "LogInComponent" } </script> <style scoped> .main{ border: 1px solid #EFEFEF; padding: 5px 10px; } </style>
子组件:DetailsComponent.vue
<template> <div> <div class="main">菜单详情</div> </div> </template> <script> export default { name: "DetailsComponent" } </script> <style scoped> .main{ border: 1px solid #EFEFEF; padding: 5px 10px; } </style>