Vue顶部tags浏览历史代码实现方法
时间:2022-06-29 02:00:06 编辑:袖梨 来源:一聚教程网
本篇文章小编给大家分享一下Vue顶部tags浏览历史代码实现方法,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
实现的功能
默认有首页,不能关闭
点击路由菜单,判断有无存在,没有就添加,有就定位到上面
点击跳转,点击X可关闭
关闭当前页,自动跳到下一个tag页面
如果当前页在最后一个,默认跳到上一个tag页面
右键菜单,刷新,关闭右侧,关闭所有
动态判断tags长多,放不下时,出现左右两侧按钮,减少时自动消失
动态判断窗口放大缩小,自动判断有无左右两侧按钮
正文
不用任何vuex,乱七八糟的方法,全在一个文件,粘贴即用
放到你想要的位置即可(此demo,放在了面包屑上面)
先安装 (监听某dom元素大小的包)
1 | npm install element-resize-detector |
tags.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | < template > < div > < div class = "tags" > <!-- 左箭头 --> < div class = "arrow arrow_left" v-show = "arrowVisible" @ click = "handleClickToLeft" > < i class = "el-icon-arrow-left" ></ i > </ div > <!-- 标签内容 --> < 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 > <!-- 右箭头 --> < div class = "arrow arrow_right" v-show = "arrowVisible" @ click = "handleClickToRight" > < i class = "el-icon-arrow-right" ></ i > </ div > </ div > <!-- 右键菜单 --> < 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" > 刷新 </ li > < li class = "el-dropdown-menu__item" @ click = "closeRightTag" > 关闭右侧 </ li > < li class = "el-dropdown-menu__item" @ click = "closeOtherTag" > 关闭其它 </ 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 { // 是否有箭头 arrowVisible: true, // 点击次数 num: 0, active: 0, tags: [], // 右键的元素 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: { // 监听可视区域宽,浏览器窗口大小改变执行 listenFun(monitor, dom) { 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"; } }); }); }, // 判断当前页 getThisPage() { let currentPgae = this.$route; // 判断tags里是否有当前页面 var index = this.tags.findIndex(tag => tag.name == currentPgae.name); if (index == -1) { this.tags.push({ name: currentPgae.name, path: currentPgae.path }); } // 当前选择页 this.active = this.tags.findIndex(tag => tag.name == currentPgae.name); }, // 关闭标签 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); } }, // 点击标签 clickTag(index, tag) { this.active = index; this.$router.push(tag.path); }, // 左侧按钮 handleClickToLeft() { if (this.num > 0) { this.num--; this.$refs.box.style.transform = `TranslateX(-${this.num * 200}px)`; } }, // 右侧按钮 handleClickToRight() { // 最后一个标签右测距离浏览器左侧距离 let lastChild = document .querySelectorAll(".top_tags") [this.tags.length - 1].getBoundingClientRect().right; // 可视窗口的宽 let bodyWidth = document.body.offsetWidth; // 右侧箭头48+右侧边距16 if (bodyWidth - lastChild <= 64) { this.num++; this.$refs.box.style.transform = `TranslateX(-${this.num * 200}px)`; } }, // 右键 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() { this.$router.go(0); }, // 关闭其他 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); }, // 关闭右侧 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() { // 监听页面刷新 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 { 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 > |
重点
需要修改的地方
currentPgae.name 是路由结构的name,判断有无存在,没有就添加,有就定位到上面,根据项目修改
监听刷新时,去本地存储 tags 和 当前页面的active,Ftistpage1 改成自己的首页即可
相关文章
- 《弓箭传说2》新手玩法介绍 01-16
- 《地下城与勇士:起源》断桥烟雨多买多送活动内容一览 01-16
- 《差不多高手》醉拳龙技能特点分享 01-16
- 《鬼谷八荒》毕方尾羽解除限制道具推荐 01-16
- 《地下城与勇士:起源》阿拉德首次迎新春活动内容一览 01-16
- 《差不多高手》情圣技能特点分享 01-16