nonsenseDemo preview Functions implementedThere is a home page by default, which cannot be closed Click the route menu to check if it exists. If not, add it. If it does, locate it above. Click to jump, click X to close Close the current page and automatically jump to the next tag page If the current page is the last one, jump to the previous tag page by default Right-click menu, refresh, close right, close all When the tags are too long to fit, buttons on the left and right sides will appear and disappear automatically when the tags are reduced. Dynamically determine whether the window is enlarged or reduced, and automatically determine whether there are buttons on the left and right sides textNo need for any vuex, messy methods, all in one file, just paste and use Just put it where you want (this demo is placed on the breadcrumbs) Install first (a package that monitors the size of a DOM element) npm install element-resize-detector tags.vue <template> <div> <div class="tags"> <!-- Left Arrow --> <div class="arrow arrow_left" v-show="arrowVisible" @click="handleClickToLeft" > <i class="el-icon-arrow-left"></i> </div> <!-- Tag content --> <div class="tags_content" ref="box"> <span ref="tags"> <el-tag v-for="(tag, index) in tags" :key="tag.name" :class="[active == index ? 'active top_tags' : 'top_tags']" effect="dark" :closable="tag.name != 'Firstpage1'" @close="handleClose(index, tag)" @click="clickTag(index, tag)" @contextmenu.native.prevent="handleClickContextMenu(index, tag)" > {{ $t("router." + tag.name) }} </el-tag> </span> </div> <!-- Right Arrow --> <div class="arrow arrow_right" v-show="arrowVisible" @click="handleClickToRight" > <i class="el-icon-arrow-right"></i> </div> </div> <!-- Right-click menu--> <ul v-show="contextMenu.isShow" :style="{ left: contextMenu.menuLeft, top: '96px' }" class="el-dropdown-menu el-popper" x-placement="bottom-end" > <li v-if="this.active == this.contextMenu.index" class="el-dropdown-menu__item" @click="refresh" > Refresh <li class="el-dropdown-menu__item" @click="closeRightTag"> Close right side</li> <li class="el-dropdown-menu__item" @click="closeOtherTag"> Close Others</li> <div x-arrow="" class="popper__arrow" style="left: 44px;"></div> </ul> </div> </template> <script> import elementResizeDetectorMaker from "element-resize-detector"; export default { data() { return { // Is there an arrow arrowVisible: true, //Number of clicks: 0, active: 0, tags: [], // Right-click element contextMenu: { index: 0, tag: {}, menuLeft: 0, isShow: false } }; }, watch: $route() { this.getThisPage(); }, tags() { this.listenFun(this.$refs.tags, "tags"); } }, mounted() { this.listenFun(this.$refs.box, "box"); var that = this; document.addEventListener("click", function(e) { that.contextMenu.isShow = false; }); }, methods: { // Monitor the width of the visible area, and execute listenFun(monitor, dom) when the browser window size changes { let boxWidth = this.$refs.box.offsetWidth, tagsWidth = this.$refs.tags.offsetWidth, erd = elementResizeDetectorMaker(); erd.listenTo(monitor, ele => { this.$nextTick(() => { if ( (dom == "box" && ele.offsetWidth >= tagsWidth) || (dom == "tags" && ele.offsetWidth <= boxWidth) ) { this.arrowVisible = false; this.$refs.box.style.paddingLeft = "16px"; this.$refs.box.style.paddingRight = "16px"; this.$refs.box.style.transform = "TranslateX(0px)"; this.num = 0; } else { this.arrowVisible = true; this.$refs.box.style.paddingLeft = "56px"; this.$refs.box.style.paddingRight = "56px"; } }); }); }, // Determine the current page getThisPage() { let currentPgae = this.$route; // Determine whether there is the current page in tags var index = this.tags.findIndex(tag => tag.name == currentPgae.name); if (index == -1) { this.tags.push({ name: currentPgae.name, path: currentPgae.path }); } //Currently selected page this.active = this.tags.findIndex(tag => tag.name == currentPgae.name); }, // Close tag handleClose(index, tag) { this.tags.splice(this.tags.indexOf(tag), 1); if (index == this.tags.length) { this.active = index - 1; this.$router.push(this.tags[index - 1].path); } else { this.$router.push(this.tags[index].path); } }, // Click the tag clickTag(index, tag) { this.active = index; this.$router.push(tag.path); }, // Left button handleClickToLeft() { if (this.num > 0) { this.num--; this.$refs.box.style.transform = `TranslateX(-${this.num * 200}px)`; } }, // Right button handleClickToRight() { // The last tag is measured from the left side of the browser let lastChild = document .querySelectorAll(".top_tags") [this.tags.length - 1].getBoundingClientRect().right; // Width of the visible window let bodyWidth = document.body.offsetWidth; // Right arrow 48 + right margin 16 if (bodyWidth - lastChild <= 64) { this.num++; this.$refs.box.style.transform = `TranslateX(-${this.num * 200}px)`; } }, // right click handleClickContextMenu(index, tag) { this.contextMenu.isShow = true; this.contextMenu.index = index; this.contextMenu.tag = tag; let isTag = document .querySelectorAll(".top_tags") [index].getBoundingClientRect(); this.contextMenu.menuLeft = isTag.left - 48 + isTag.width / 2 + "px"; }, // Refresh refresh() { this.$router.go(0); }, // Close other closeOtherTag() { let tagsLin = this.tags.length, { index, tag, menuLeft } = this.contextMenu; if (index != 0) { this.tags = [ { name: "Firstpage1", path: "/First/page1" }, { name: tag.name, path: tag.path } ]; } else { this.tags = [ { name: "Firstpage1", path: "/First/page1" } ]; } this.active = index; this.$router.push(tag.path); }, // Close the right side closeRightTag() { let tagsLin = this.tags.length, { index, tag, menuLeft } = this.contextMenu; this.tags.splice(index + 1, tagsLin - index); this.active = index; this.$router.push(tag.path); } }, created() { // Listen for page refresh window.addEventListener("beforeunload", e => { localStorage.setItem( "tagInfo", JSON.stringify({ active: this.active, tags: this.tags }) ); }); let tagInfo = localStorage.getItem("tagInfo") ? JSON.parse(localStorage.getItem("tagInfo")) : { active: 0, tags: [ { name: "Firstpage1", path: "/First/page1" } ] }; this.active = tagInfo.active; this.tags = tagInfo.tags; } }; </script> <style lang="less" scoped> /deep/.el-tag--dark { border-color: transparent; } /deep/.el-tag--dark .el-tag__close { color: #86909c; font-size: 16px; } /deep/.el-tag--dark .el-tag__close:hover { background: #e7eaf0; } .tags { position: relative; overflow: hidden; .arrow { width: 48px; text-align: center; cursor: pointer; background: #fff; position: absolute; z-index: 1; &_left { left: 0; top: 0; } &_right { right: 0; top: 0; } } &_content { transition: 0.3s; white-space: nowrap; // padding: 0 16px; } .top_tags { margin-right: 8px; cursor: pointer; background: #fff; font-size: 12px; font-weight: 400; color: #1d2129; } .top_tags:hover, .active, .arrow:hover { background: #e7eaf0; } } </style> Key PointsWhat needs to be modified currentPgae.name is the name of the routing structure. Check if it exists. If not, add it. If yes, locate it above. Modify it according to the project When monitoring refresh, go to local storage tags and the active of the current page, and change Ftistpage1 to your own homepage This is the end of this article about the implementation of Vue top tags browsing history. For more relevant Vue top tags browsing history content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Example of compiling LNMP in Docker container
>>: CSS3 simple cutting carousel picture implementation code
//MySQL statement SELECT * FROM `MyTable` WHERE `...
This article records the installation and configu...
Table of contents A murder caused by ERR 1067 The...
Install jdk: Oracle official download https://www...
Tomcat defines multiple ClassLoaders internally s...
Because I have always used vscode to develop fron...
Preface Normally, if we want to delete certain li...
Effect There are currently 2 projects (project1, ...
Table of contents Preface Achieve results Code CS...
Volume data volume is an important concept of Doc...
1. Introduction I want to use selenium to scrape ...
Table of contents JavaScript function call classi...
This article shares with you the installation tut...
MySQL supports many types of tables (i.e. storage...