Vue頂部tags瀏覽歷史的實現(xiàn)
廢話


實現(xiàn)的功能
默認有首頁,不能關閉
點擊路由菜單,判斷有無存在,沒有就添加,有就定位到上面
點擊跳轉,點擊X可關閉
關閉當前頁,自動跳到下一個tag頁面
如果當前頁在最后一個,默認跳到上一個tag頁面
右鍵菜單,刷新,關閉右側,關閉所有
動態(tài)判斷tags長多,放不下時,出現(xiàn)左右兩側按鈕,減少時自動消失
動態(tài)判斷窗口放大縮小,自動判斷有無左右兩側按鈕
正文
不用任何vuex,亂七八糟的方法,全在一個文件,粘貼即用

放到你想要的位置即可(此demo,放在了面包屑上面)
先安裝 (監(jiān)聽某dom元素大小的包)
npm install element-resize-detector
tags.vue
<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,
// 點擊次數(shù)
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: {
// 監(jiān)聽可視區(qū)域寬,瀏覽器窗口大小改變執(zhí)行
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() {
// 監(jiān)聽頁面刷新
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>
重點
需要修改的地方

currentPgae.name 是路由結構的name,判斷有無存在,沒有就添加,有就定位到上面,根據(jù)項目修改

監(jiān)聽刷新時,去本地存儲 tags 和 當前頁面的active,F(xiàn)tistpage1 改成自己的首頁即可?
到此這篇關于Vue頂部tags瀏覽歷史的實現(xiàn)的文章就介紹到這了,更多相關Vue頂部tags瀏覽歷史內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue項目如何監(jiān)聽localStorage或sessionStorage的變化
這篇文章主要介紹了vue 項目如何監(jiān)聽localStorage或sessionStorage的變化,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01
vue+elementUI實現(xiàn)動態(tài)面包屑
這篇文章主要為大家詳細介紹了vue+elementUI實現(xiàn)動態(tài)面包屑,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04

