diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue index 34a7e55f..655b6cce 100644 --- a/src/layout/components/TagsView/ScrollPane.vue +++ b/src/layout/components/TagsView/ScrollPane.vue @@ -34,11 +34,12 @@ export default { emitScroll() { this.$emit('scroll') }, - moveToTarget(currentTag) { + moveToTarget(currentRoute) { const $container = this.$refs.scrollContainer.$el const $containerWidth = $container.offsetWidth const $scrollWrapper = this.scrollWrapper - const tagList = this.$parent.$refs.tag + const tagList = Array.from(window.document.querySelectorAll('#tags-view-container .tags-view-item')) + const currentTag = tagList.find(i => i.dataset.fullPath === currentRoute.fullPath) let firstTag = null let lastTag = null @@ -60,10 +61,10 @@ export default { const nextTag = tagList[currentIndex + 1] // the tag's offsetLeft after of nextTag - const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing + const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing // the tag's offsetLeft before of prevTag - const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing + const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue index d2a56e70..7a3d3067 100644 --- a/src/layout/components/TagsView/index.vue +++ b/src/layout/components/TagsView/index.vue @@ -1,20 +1,22 @@ <template> <div id="tags-view-container" class="tags-view-container"> <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll"> - <router-link - v-for="tag in visitedViews" - ref="tag" - :key="tag.path" - :class="isActive(tag)?'active':''" - :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" - tag="span" - class="tags-view-item" - @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" - @contextmenu.prevent.native="openMenu(tag,$event)" - > - {{ tag.title }} - <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> - </router-link> + <div ref="sortable-wrap"> + <router-link + v-for="tag in visitedViews" + :key="tag.path" + :class="{ active: isActive(tag), sortable: !isAffix(tag) }" + :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" + tag="span" + class="tags-view-item" + :data-full-path="tag.fullPath" + @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" + @contextmenu.prevent.native="openMenu(tag,$event)" + > + {{ tag.title }} + <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> + </router-link> + </div> </scroll-pane> <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> <li @click="refreshSelectedTag(selectedTag)">Refresh</li> @@ -28,6 +30,7 @@ <script> import ScrollPane from './ScrollPane' import path from 'path' +import Sortable from 'sortablejs' export default { components: { ScrollPane }, @@ -64,6 +67,7 @@ export default { mounted() { this.initTags() this.addTags() + this.initSortableTags() }, methods: { isActive(route) { @@ -104,24 +108,32 @@ export default { }, addTags() { const { name } = this.$route - if (name) { + if (!name) { + return + } + const res = this.visitedViews.find(v => v.path === this.$route.path) + if (res) { + // when query is different then update + if (res.fullPath !== this.$route.fullPath) { + this.$store.dispatch('tagsView/updateVisitedView', this.$route) + } + } else { this.$store.dispatch('tagsView/addView', this.$route) } - return false + }, + initSortableTags() { + new Sortable(this.$refs['sortable-wrap'], { + draggable: '.sortable', + animation: 200, + onUpdate: event => { + const { oldIndex, newIndex } = event + this.$store.dispatch('tagsView/moveView', { oldIndex, newIndex }) + } + }) }, moveToCurrentTag() { - const tags = this.$refs.tag this.$nextTick(() => { - for (const tag of tags) { - if (tag.to.path === this.$route.path) { - this.$refs.scrollPane.moveToTarget(tag) - // when query is different then update - if (tag.to.fullPath !== this.$route.fullPath) { - this.$store.dispatch('tagsView/updateVisitedView', this.$route) - } - break - } - } + this.$refs.scrollPane.moveToTarget(this.$route) }) }, refreshSelectedTag(view) { diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js index 57e72421..ab2ec298 100644 --- a/src/store/modules/tagsView.js +++ b/src/store/modules/tagsView.js @@ -63,6 +63,9 @@ const mutations = { break } } + }, + MOVE_VIEW: (state, { oldIndex, newIndex }) => { + state.visitedViews.splice(newIndex, 0, state.visitedViews.splice(oldIndex, 1)[0]) } } @@ -149,6 +152,9 @@ const actions = { updateVisitedView({ commit }, view) { commit('UPDATE_VISITED_VIEW', view) + }, + moveView({ commit }, arg) { + commit('MOVE_VIEW', arg) } }