業(yè)務(wù)場景
微前端子應(yīng)用間加tab,做到菜單切換
效果
類似效果
涉及問題
因?yàn)檫@是加在每個子應(yīng)用間窃页,所以需要在每個子應(yīng)用都加上tabs組件跺株,切換的菜單如何在每個子應(yīng)用更新?
處理方案
思路就是將我們點(diǎn)擊的菜單保存到localStorage中脖卖,然后每個子應(yīng)用去監(jiān)聽localStorage值的變化乒省,從而更新tabs組件的值。
在資源文件中新建locale.js
export default function dispatchEventStroage () {
let signSetItem = localStorage.setItem
localStorage.setItem = function (key, val) {
let setEvent = new Event('setItemEvent')
setEvent.key = key
setEvent.newValue = val
window.dispatchEvent(setEvent)
signSetItem.apply(this, arguments)
}
}
在index.js中引用這個js畦木,我這里是放在plugins文件夾下
import tool from '@/plugins/locale';
Vue.use(tool);
在App.vue加上tabs這個組件
<template>
<div class="app" @click="down">
<!-- 加載tabs組件 -->
<a-tabs
v-model="activeKey"
type="editable-card"
hideAdd
@edit="onEdit"
@change="onChange"
@contextmenu.prevent="open($event)"
>
<a-tab-pane
v-for="pane in initalItem"
:key="pane.key"
:tab="pane.title"
:closable="pane.closable"
>
<!-- 這里做的是自定義右鍵 -->
<ul
v-show="visible"
:style="{ left: left + 'px', top: top + 'px' }"
class="newcontextmenu"
>
<li @click="close">關(guān)閉標(biāo)簽</li>
<li @click="closeAll">關(guān)閉所有標(biāo)簽</li>
</ul>
</a-tab-pane>
</a-tabs>
<div class="app-main">
<router-view />
</div>
</div>
</template>
<script>
export default {
data() {
return {
activeKey: this.$route.path,
initalItem: JSON.parse(localStorage.getItem("initalItem")),
visible: false,
top: 0,
left: 0,
};
},
created() {},
mounted() {
let that = this;
// 監(jiān)聽localStorage的值的變化
this.$nextTick(function () {
window.addEventListener("setItemEvent", (e) => {
setTimeout(function () {
that.initalItem = JSON.parse(localStorage.getItem("initalItem"));
});
setTimeout(function () {
that.activeKey = that.$route.path;
});
});
});
},
methods: {
onEdit(targetKey, action) {
if (action == "remove") {
const initalItem = JSON.parse(localStorage.getItem("initalItem"));
initalItem.splice(
initalItem.findIndex((item) => item.key === targetKey),
1
);
localStorage.setItem("initalItem", JSON.stringify(initalItem));
this.initalItem = initalItem;
this.activeKey = initalItem[initalItem.length - 1].key;
this.$router.push(this.activeKey);
}
},
onChange(targetKey) {
const initalItem = JSON.parse(localStorage.getItem("initalItem"));
let data = initalItem.find((item) => item.key == targetKey);
this.$router.push({
path: targetKey,
query: data.query,
});
},
open(e) {
this.visible = false;
var x = e.pageX + 50;
var y = e.pageY;
this.top = y;
this.left = x;
this.visible = true;
},
down() {
this.visible = false;
},
close() {
const initalItem = JSON.parse(localStorage.getItem("initalItem"));
initalItem.splice(
initalItem.findIndex((item) => item.key === this.activeKey),
1
);
localStorage.setItem("initalItem", JSON.stringify(initalItem));
this.initalItem = initalItem;
this.activeKey = initalItem[initalItem.length - 1].key;
this.$router.push(this.activeKey);
},
closeAll() {
localStorage.setItem(
"initalItem",
JSON.stringify([
{
title: "首頁",
key: "/index",
closable: false,
},
])
);
this.initalItem = [
{
title: "首頁",
key: "/index",
closable: false,
},
];
this.activeKey = "/index";
this.$router.push("/index");
},
},
};
</script>
<style lang="less">
.newcontextmenu {
position: fixed;
border: 1px solid #ccc;
border-radius: 5px;
background: #fff;
li {
padding: 10px;
cursor: pointer;
}
}
</style>
修改router.js
//去重袖扛,后面點(diǎn)擊的覆蓋前面點(diǎn)擊的(對應(yīng)的key值)
function deWeight(arr) {
let map = new Map();
for(let item of arr){
map.set(item.key,item)
}
return [...map.values()];
}
router.beforeEach(async (to, from, next) => {
let array = JSON.parse(localStorage.getItem("initalItem"))?JSON.parse(localStorage.getItem("initalItem")):[]
if(to.path === '/index'){
array.push({
title: '首頁',
key: to.path,
closable: false
})
}else{
array.push({
title: to.meta.title,
key: to.path,
query: to.query
})
}
localStorage.setItem("initalItem",JSON.stringify(deWeight(array)));
});
這是其中一個子應(yīng)用的配置,另一個子應(yīng)用也是相對應(yīng)的配置馋劈。