
将标签存放在Tags.vue,使用组件传值进行切换。增加keep-alive缓存机制
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组件
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()
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 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- 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 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>