实现同一个组件页面通过不同的tab标签页打开

Posted 千秋岁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现同一个组件页面通过不同的tab标签页打开相关的知识,希望对你有一定的参考价值。

首先展示一下效果页面

将标签存放在Tags.vue,使用组件传值进行切换。增加keep-alive缓存机制

  

1、在home页面或主页面注册tabs组件

  

 1 <el-main style="background-color:#eaedf1">
 2         <!-- 标签组件 -->
 3         <tabs></tabs>
 4         <router-view></router-view>
 5         <!-- 增加keep-alive缓存机制 -->
 6         <keep-alive :include="tagsList">
 7             <router-view></router-view>
 8         </keep-alive>
 9       </el-main>
10 
11 在home页面或主页面注册tabs组件
2、在home页面或者主页面进行传值
 1  <script>
 2   import Tabs from \'@/components/common/Tags.vue\'  // 引入Tags组件
 3   import bus from \'@/components/common/bus.js\'  // 组件传值使用的bus
 4   export default {
 5     created() {
 6       // 用于keep-alive缓存,只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。
 7       bus.$on(\'tags\', msg => {
 8         let arr = []
 9         for (let i = 0, len = msg.length; i < len; i++) {
10          msg[i].name && arr.push(msg[i].name)
11        }
12        this.tagsList = arr
13      })
14    },
15    components: {
16      tabs: Tabs,   // 注册tabs组件
17      bus,    // 注册bus组件传值公共文件 
18    },
19    data() {
20      return {
21        tagsList: [],
22      }
23    },
24    methods: {},
25  }
26  </script>
3、新建一个bus.js文件,通用bus.js组件传值
1 import Vue from \'vue\';
2 export default new Vue()
4、Tags.vue组件
1 <template>
  2   <div class="tags" v-if="showTags">
  3     <!-- 标签列表 -->
  4     <ul>
  5       <li
  6         class="tags-li"
  7         v-for="(item,index) in tagsList"
  8         :class="{\'active\': isActive(item.path)}"
  9         :key="index"
 10       >
 11         <router-link :to="item.path" class="tags-li-title">{{item.title}}</router-link>
 12         <span class="tags-li-icon" @click="closeTags(index)">
 13           <i class="el-icon-close"></i>
 14         </span>
 15       </li>
 16     </ul>
 17     <div class="tags-close-box">
 18       <!-- elementUi下拉菜单 -->
 19       <el-dropdown @command="handleTags">
 20         <el-button size="mini" type="primary">
 21           标签选项
 22           <i class="el-icon-arrow-down el-icon--right"></i>
 23         </el-button>
 24         <el-dropdown-menu size="small" slot="dropdown">
 25           <el-dropdown-item command="other">关闭其他</el-dropdown-item>
 26           <el-dropdown-item command="all">关闭所有</el-dropdown-item>
 27         </el-dropdown-menu>
 28       </el-dropdown>
 29     </div>
 30   </div>
 31 </template>
 32 
 33 <script>
 34 import bus from "./bus";  // 引入通用组件传值组件
 35 export default {
 36   data() {
 37     return {
 38       tagsList: [], // 存放所有标签
 39     };
 40   },
 41   methods: {
 42     // 当前选中标签
 43     isActive(path) {
 44       return path === this.$route.fullPath;
 45     },
 46     // 关闭单个标签
 47     closeTags(index) {
 48       const delItem = this.tagsList.splice(index, 1)[0];
 49       const item = this.tagsList[index]
 50         ? this.tagsList[index]
 51         : this.tagsList[index - 1];
 52       if (item) {
 53         delItem.path === this.$route.fullPath && this.$router.push(item.path);
 54       } else {
 55         this.$router.push("/");
 56       }
 57     },
 58     // 关闭全部标签
 59     closeAll() {
 60       this.tagsList = [];
 61       this.$router.push("/");
 62     },
 63     // 关闭其他标签
 64     closeOther() {
 65       const curItem = this.tagsList.filter(item => {
 66         return item.path === this.$route.fullPath;
 67       });
 68       this.tagsList = curItem;
 69     },
 70     // 设置标签
 71     setTags(route) {
 72       const isExist = this.tagsList.some(item => {
 73         return item.path === route.fullPath;
 74       });
 75       if (!isExist) {
 76         if (this.tagsList.length >= 8) {
 77           this.tagsList.shift();
 78         }
 79         this.tagsList.push({
 80           title: route.meta.title,
 81           path: route.fullPath,
 82           name: route.matched[1].components.default.name
 83         });
 84       }
 85       bus.$emit("tags", this.tagsList); // 组件传值
 86     },
 87     // 点击标签下拉选项(关闭其他或者关闭所有)
 88     handleTags(command) {
 89       command === "other" ? this.closeOther() : this.closeAll();
 90     }
 91   },
 92   computed: {
 93     // 大于0则显示标签组件
 94     showTags() {
 95       return this.tagsList.length > 0;
 96     }
 97   },
 98   watch: {
 99     // 当$route发生变化重新赋值
100     $route(newValue, oldValue) {
101       this.setTags(newValue);
102     }
103   },
104   created() {
105     this.setTags(this.$route);
106   }
107 };
108 </script>
109 
110 
111 <style>
112 .tags {
113   position: relative;
114   height: 30px;
115   overflow: hidden;
116   background: #fff;
117   padding-right: 120px;
118   box-shadow: 0 5px 10px #ddd;
119 }
120 
121 .tags ul {
122   box-sizing: border-box;
123   width: 100%;
124   height: 100%;
125 }
126 
127 .tags-li {
128   float: left;
129   margin: 3px 5px 2px 3px;
130   border-radius: 3px;
131   font-size: 12px;
132   overflow: hidden;
133   cursor: pointer;
134   height: 23px;
135   line-height: 23px;
136   border: 1px solid #e9eaec;
137   background: #fff;
138   padding: 0 5px 0 12px;
139   vertical-align: middle;
140   color: #666;
141   -webkit-transition: all 0.3s ease-in;
142   -moz-transition: all 0.3s ease-in;
143   transition: all 0.3s ease-in;
144 }
145 
146 .tags-li:not(.active):hover {
147   background: #f8f8f8;
148 }
149 
150 .tags-li.active {
151   color: #fff;
152 }
153 
154 .tags-li-title {
155   float: left;
156   max-width: 80px;
157   overflow: hidden;
158   white-space: nowrap;
159   text-overflow: ellipsis;
160   margin-right: 5px;
161   color: #666;
162 }
163 
164 .tags-li.active .tags-li-title {
165   color: #fff;
166 }
167 .tags-li.active {
168     border: 1px solid #409EFF;
169     background-color: #409EFF;
170 }
171 a {
172     text-decoration: none;
173 }
174 .tags-close-box {
175   position: absolute;
176   right: 0;
177   top: 0;
178   box-sizing: border-box;
179   padding-top: 1px;
180   text-align: center;
181   width: 110px;
182   height: 30px;
183   background: #fff;
184   box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
185   z-index: 10;
186 }
187 </style>

 

以上是关于实现同一个组件页面通过不同的tab标签页打开的主要内容,如果未能解决你的问题,请参考以下文章

Vue实现简单Tab标签页组件

antd源码分析之——标签页(tabs 2.Tabs关键组件功能实现)

element的标签页(tabs)组件样式自定义

vue中tab标签页keep-alive二级路由+删除指定缓存页面

Easyui 实现点击不同树节点打开不同tab页展示不同datagrid表数据设计

antd源码分析之——标签页(tabs 3.Tabs的滚动效果)