|
@@ -1,23 +1,28 @@
|
|
|
<template>
|
|
|
<div class="tags-view-container">
|
|
|
- <scroll-pane class='tags-view-wrapper'
|
|
|
- ref='scrollPane'>
|
|
|
- <router-link ref='tag'
|
|
|
- class="tags-view-item"
|
|
|
- :class="isActive(tag)?'active':''"
|
|
|
- v-for="(tag,index) in Array.from(visitedViews)"
|
|
|
- :to="{path:tag.fullPath,query:tag.query,some:tag.path}"
|
|
|
- :key="index"
|
|
|
- @contextmenu.prevent.native="openMenu(tag,$event)">
|
|
|
- {{generateTitle(tag.title)}}
|
|
|
+ <scroll-pane class="tags-view-wrapper" ref="scrollPane">
|
|
|
+ <router-link
|
|
|
+ ref="tag"
|
|
|
+ class="tags-view-item"
|
|
|
+ :class="isActive(tag) ? 'active' : ''"
|
|
|
+ v-for="(tag, index) in Array.from(visitedViews)"
|
|
|
+ :to="{ path: tag.fullPath, query: tag.query, some: tag.path }"
|
|
|
+ :key="index"
|
|
|
+ @contextmenu.prevent.native="openMenu(tag, $event)"
|
|
|
+ >
|
|
|
+ {{ generateTitle(tag.title) }}
|
|
|
<!-- v-if="index == Array.from(visitedViews).length -1" -->
|
|
|
- <span class='el-icon-close'
|
|
|
- @click.prevent.stop='closeSelectedTag(tag)'></span>
|
|
|
+ <span
|
|
|
+ class="el-icon-close icon"
|
|
|
+ @click.prevent.stop="closeSelectedTag(tag)"
|
|
|
+ ></span>
|
|
|
</router-link>
|
|
|
</scroll-pane>
|
|
|
- <ul class='contextmenu'
|
|
|
- v-show="visible"
|
|
|
- :style="{left:left+'px',top:top+'px'}">
|
|
|
+ <ul
|
|
|
+ class="contextmenu"
|
|
|
+ v-show="visible"
|
|
|
+ :style="{ left: left + 'px', top: top + 'px' }"
|
|
|
+ >
|
|
|
<li @click="closeSelectedTag(selectedTag)">关闭</li>
|
|
|
<li @click="closeOthersTags">关闭其他</li>
|
|
|
<li @click="closeAllTags">关闭所有</li>
|
|
@@ -27,166 +32,180 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import ScrollPane from '@/components/ScrollPane'
|
|
|
-import { generateTitle } from '@/utils/i18n'
|
|
|
-import { Searchs } from '@/helpers'
|
|
|
+import ScrollPane from "@/components/ScrollPane";
|
|
|
+import { generateTitle } from "@/utils/i18n";
|
|
|
+import { Searchs } from "@/helpers";
|
|
|
|
|
|
export default {
|
|
|
- name: 'TagsView',
|
|
|
+ name: "TagsView",
|
|
|
components: { ScrollPane },
|
|
|
- data () {
|
|
|
+ data() {
|
|
|
return {
|
|
|
visible: false,
|
|
|
top: 0,
|
|
|
left: 0,
|
|
|
- selectedTag: {}
|
|
|
- }
|
|
|
+ selectedTag: {},
|
|
|
+ };
|
|
|
},
|
|
|
- inject: ['reloads'],
|
|
|
+ inject: ["reloads"],
|
|
|
computed: {
|
|
|
- visitedViews () {
|
|
|
+ visitedViews() {
|
|
|
// console.log(this.$store.state.tagsView.visitedViews)
|
|
|
- return this.$store.state.tagsView.visitedViews
|
|
|
- }
|
|
|
+ return this.$store.state.tagsView.visitedViews;
|
|
|
+ },
|
|
|
},
|
|
|
watch: {
|
|
|
- $route () {
|
|
|
- this.addViewTags()
|
|
|
- this.moveToCurrentTag()
|
|
|
+ $route() {
|
|
|
+ this.addViewTags();
|
|
|
+ this.moveToCurrentTag();
|
|
|
},
|
|
|
- visible (value) {
|
|
|
+ visible(value) {
|
|
|
if (value) {
|
|
|
- document.body.addEventListener('click', this.closeMenu)
|
|
|
+ document.body.addEventListener("click", this.closeMenu);
|
|
|
} else {
|
|
|
- document.body.removeEventListener('click', this.closeMenu)
|
|
|
+ document.body.removeEventListener("click", this.closeMenu);
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
},
|
|
|
- mounted () {
|
|
|
- this.addViewTags()
|
|
|
-
|
|
|
+ mounted() {
|
|
|
+ this.addViewTags();
|
|
|
},
|
|
|
methods: {
|
|
|
// generateTitle by vue-i18n
|
|
|
generateTitle,
|
|
|
- generateRoute () {
|
|
|
- if (this.$route.path && this.$route.path != '/') {
|
|
|
- return this.$route
|
|
|
+ generateRoute() {
|
|
|
+ if (this.$route.path && this.$route.path != "/") {
|
|
|
+ return this.$route;
|
|
|
}
|
|
|
- return false
|
|
|
+ return false;
|
|
|
},
|
|
|
// || route.name === this.$route.name
|
|
|
- isActive (route) {
|
|
|
- return route.path === this.$route.path
|
|
|
+ isActive(route) {
|
|
|
+ return route.path === this.$route.path;
|
|
|
},
|
|
|
syncTagViewAndSaveForm() {
|
|
|
- const keys = this.$store.state.tagsView.visitedViews.map(item => item.path)
|
|
|
- const searchs = new Searchs()
|
|
|
- const allSearch = searchs.getSearchs()
|
|
|
- const sks = Object.keys(allSearch)
|
|
|
+ const keys = this.$store.state.tagsView.visitedViews.map(
|
|
|
+ (item) => item.path
|
|
|
+ );
|
|
|
+ const searchs = new Searchs();
|
|
|
+ const allSearch = searchs.getSearchs();
|
|
|
+ const sks = Object.keys(allSearch);
|
|
|
for (const item of sks) {
|
|
|
if (!(keys.includes(item) || keys.includes(allSearch[item].bind))) {
|
|
|
- searchs.removeByKey(item)
|
|
|
+ searchs.removeByKey(item);
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- async addViewTags () {
|
|
|
- const route = this.generateRoute()
|
|
|
+ async addViewTags() {
|
|
|
+ const route = this.generateRoute();
|
|
|
if (!route) {
|
|
|
- return false
|
|
|
+ return false;
|
|
|
}
|
|
|
// console.log(this.$route)
|
|
|
- await this.$store.dispatch('addVisitedViews', route)
|
|
|
- this.syncTagViewAndSaveForm()
|
|
|
+ await this.$store.dispatch("addVisitedViews", route);
|
|
|
+ this.syncTagViewAndSaveForm();
|
|
|
},
|
|
|
- moveToCurrentTag () {
|
|
|
- const tags = this.$refs['tag']
|
|
|
+ moveToCurrentTag() {
|
|
|
+ const tags = this.$refs["tag"];
|
|
|
this.$nextTick(() => {
|
|
|
for (const tag of tags) {
|
|
|
if (tag.path === this.$route.path) {
|
|
|
- this.$refs.scrollPane.moveToTarget(tag.$el)
|
|
|
- break
|
|
|
+ this.$refs.scrollPane.moveToTarget(tag.$el);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
},
|
|
|
- closeSelectedTag (view) {
|
|
|
- const searchs = new Searchs()
|
|
|
- searchs.remove(this.$route.path)
|
|
|
- this.$store.dispatch('delVisitedViews', view).then((views) => {
|
|
|
+ closeSelectedTag(view) {
|
|
|
+ const searchs = new Searchs();
|
|
|
+ searchs.remove(this.$route.path);
|
|
|
+ this.$store.dispatch("delVisitedViews", view).then((views) => {
|
|
|
if (this.isActive(view)) {
|
|
|
- const latestView = views.slice(-1)[0]
|
|
|
+ const latestView = views.slice(-1)[0];
|
|
|
if (latestView) {
|
|
|
- this.$router.push(latestView.fullPath)
|
|
|
+ this.$router.push(latestView.fullPath);
|
|
|
} else {
|
|
|
- this.$router.push('/')
|
|
|
+ this.$router.push("/");
|
|
|
}
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
},
|
|
|
- closeOthersTags () {
|
|
|
- this.$router.push(this.selectedTag.path)
|
|
|
- this.$store.dispatch('delOthersViews', this.selectedTag).then(() => {
|
|
|
- this.moveToCurrentTag()
|
|
|
- })
|
|
|
+ closeOthersTags() {
|
|
|
+ this.$router.push(this.selectedTag.path);
|
|
|
+ this.$store.dispatch("delOthersViews", this.selectedTag).then(() => {
|
|
|
+ this.moveToCurrentTag();
|
|
|
+ });
|
|
|
},
|
|
|
- closeAllTags () {
|
|
|
- this.$store.dispatch('delAllViews')
|
|
|
- this.$router.push('/')
|
|
|
+ closeAllTags() {
|
|
|
+ this.$store.dispatch("delAllViews");
|
|
|
+ this.$router.push("/");
|
|
|
},
|
|
|
- openMenu (tag, e) {
|
|
|
- this.visible = true
|
|
|
- this.selectedTag = tag
|
|
|
- this.left = e.clientX - 165
|
|
|
- this.top = e.clientY + 15
|
|
|
+ openMenu(tag, e) {
|
|
|
+ this.visible = true;
|
|
|
+ this.selectedTag = tag;
|
|
|
+ this.left = e.clientX - 165;
|
|
|
+ this.top = e.clientY + 15;
|
|
|
},
|
|
|
- closeMenu () {
|
|
|
- this.visible = false
|
|
|
+ closeMenu() {
|
|
|
+ this.visible = false;
|
|
|
},
|
|
|
- async refresh (view) {
|
|
|
- await this.reloads()
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+ async refresh(view) {
|
|
|
+ await this.reloads();
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
.tags-view-container {
|
|
|
.tags-view-wrapper {
|
|
|
- background: #fff;
|
|
|
+ background: #edeef0;
|
|
|
height: 34px;
|
|
|
border-bottom: 1px solid #d8dce5;
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
|
|
|
.tags-view-item {
|
|
|
+ width: 120px;
|
|
|
+ .icon {
|
|
|
+ font-size: 20px;
|
|
|
+ position: relative;
|
|
|
+ top: 3px;
|
|
|
+ float: right;
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ border-radius: 5px 5px 0 0;
|
|
|
display: inline-block;
|
|
|
position: relative;
|
|
|
- height: 26px;
|
|
|
- line-height: 26px;
|
|
|
- border: 1px solid #d8dce5;
|
|
|
+ height: 30px;
|
|
|
+ line-height: 30px;
|
|
|
+ // border: 1px solid #d8dce5;
|
|
|
color: #495060;
|
|
|
- background: #fff;
|
|
|
+
|
|
|
padding: 0 8px;
|
|
|
font-size: 12px;
|
|
|
- margin-left: 5px;
|
|
|
+ // margin-left: 5px;
|
|
|
margin-top: 4px;
|
|
|
&:first-of-type {
|
|
|
margin-left: 15px;
|
|
|
}
|
|
|
&.active {
|
|
|
- background-color: #13817a;
|
|
|
- color: #fff;
|
|
|
- border-color: #13817a;
|
|
|
+ color: #495060;
|
|
|
+ left: -1px;
|
|
|
+ background-color: #fff;
|
|
|
+ z-index: 2;
|
|
|
+
|
|
|
&::before {
|
|
|
- content: "";
|
|
|
- background: #fff;
|
|
|
- display: inline-block;
|
|
|
- width: 8px;
|
|
|
- height: 8px;
|
|
|
- border-radius: 50%;
|
|
|
- position: relative;
|
|
|
- margin-right: 2px;
|
|
|
+ border-right: 0;
|
|
|
}
|
|
|
}
|
|
|
+ &::before {
|
|
|
+ content: "";
|
|
|
+ display: inline-block;
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ height: 20px;
|
|
|
+ bottom: 6px;
|
|
|
+ border-right: 1px solid #b5b5b5;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
.contextmenu {
|