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
This article records the detailed process of down...
This article shares a small example of adding and...
Table of contents 1. WordPress deployment 1. Prep...
When a web project gets bigger and bigger, its CS...
1. Rendering 2. Source code HTML < body > &...
Table of contents 1 Question 2 Methods 3 Experime...
This time we use HTML+CSS layout to make a prelim...
1. After connecting and logging in to MySQL, firs...
We all know that the commonly used positioning me...
Table of contents 1. fill() syntax 2. Use of fill...
WeChat applet: Simple calculator, for your refere...
Table of contents Nginx load balancing configurat...
Table of contents 1. Log related services 2. Comm...
When I first came into contact with HTML, I alway...
1. Install tomcat8 with docker 1. Find the tomcat...