'admin-21.02.04:处理分栏布局菜单高亮、编写用户按钮权限组件'

This commit is contained in:
lyt 2021-02-04 18:13:03 +08:00
parent 9586a55808
commit 097f87317f
14 changed files with 309 additions and 50 deletions

View File

@ -0,0 +1,29 @@
<template>
<div v-if="getUserAuthList">
<slot />
</div>
</template>
<script lang="ts">
import { computed } from "vue";
import { useStore } from "/@/store/index.ts";
export default {
props: {
value: {
type: String,
default: () => "",
},
},
nane: "auth",
setup(props) {
const store = useStore();
// vuex
const getUserAuthList = computed(() => {
return store.state.auths.some((v) => v === props.value);
});
return {
getUserAuthList,
};
},
};
</script>

View File

@ -0,0 +1,31 @@
<template>
{{getUserAuthList}}
<div v-if="getUserAuthList">
<slot />
</div>
</template>
<script lang="ts">
import { computed } from "vue";
import { useStore } from "/@/store/index.ts";
export default {
nane: "authAll",
props: {
value: {
type: Array,
default: () => [],
},
},
setup(props) {
const store = useStore();
console.log(store.state);
// vuex
const getUserAuthList = computed(() => {
return false;
});
return {
getUserAuthList,
};
},
};
</script>

View File

@ -0,0 +1,35 @@
<template>
<div v-if="getUserAuthList">
<slot />
</div>
</template>
<script lang="ts">
import { computed } from "vue";
import { useStore } from "/@/store/index.ts";
export default {
props: {
value: {
type: Array,
default: () => [],
},
},
nane: "auths",
setup(props) {
const store = useStore();
// vuex
const getUserAuthList = computed(() => {
let flag = false;
store.state.auths.map((val) => {
props.value.map((v) => {
if (val === v) flag = true;
});
});
return flag;
});
return {
getUserAuthList,
};
},
};
</script>

View File

@ -1,21 +0,0 @@
<template>
<div>
componentsIndex
<el-input v-model="val"></el-input>
</div>
</template>
<script lang="ts">
import { toRefs, reactive } from "vue";
export default {
name: "componentsIndex",
setup() {
const state = reactive({
val: "",
});
return {
...toRefs(state),
};
},
};
</script>

View File

@ -108,6 +108,8 @@ export default {
//
watch(store.state, (val) => {
if (val.routes.length === state.menuList.length) return false;
let { layout, isClassicSplitMenu } = val.themeConfig;
if (layout === "classic" && isClassicSplitMenu) return false;
setFilterRoutes();
});
//
@ -119,8 +121,10 @@ export default {
});
proxy.mittBus.on("setSendClassicChildren", (res) => {
let { layout, isClassicSplitMenu } = store.state.themeConfig;
if (layout === "classic" && isClassicSplitMenu)
if (layout === "classic" && isClassicSplitMenu) {
state.menuList = [];
state.menuList = res.children;
}
});
proxy.mittBus.on("getBreadcrumbIndexSetFilterRoutes", () => {
setFilterRoutes();

View File

@ -35,6 +35,7 @@ import {
onMounted,
nextTick,
getCurrentInstance,
watch,
} from "vue";
import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router";
import { useStore } from "/@/store/index.ts";
@ -51,6 +52,7 @@ export default {
columnsAsideList: [],
liIndex: 0,
difference: 0,
routeSplit: [],
});
//
const setColumnsAsideStyle = computed(() => {
@ -64,7 +66,7 @@ export default {
return "layout-columns-card-active";
});
//
const setColumnsAsideMove = (v: Object, k: number) => {
const setColumnsAsideMove = (k: number) => {
state.liIndex = k;
columnsAsideActiveRef.value.style.top = `${
columnsAsideOffsetTopRefs.value[k].offsetTop + state.difference
@ -72,22 +74,22 @@ export default {
};
//
const onColumnsAsideMenuClick = (v: Object, k: number) => {
setColumnsAsideMove(v, k);
setColumnsAsideMove(k);
let { path, redirect } = v;
if (redirect) router.push(redirect);
else router.push(path);
};
//
const onColumnsAsideDown = (v: Object, k: number) => {
const onColumnsAsideDown = (k: number) => {
nextTick(() => {
setColumnsAsideMove(v, k);
setColumnsAsideMove(k);
});
};
// //
const setFilterRoutes = () => {
state.columnsAsideList = filterRoutesFun(store.state.routes);
const resData = setSendChildren(route.path);
onColumnsAsideDown(resData.item[0], resData.item[0].k);
onColumnsAsideDown(resData.item[0].k);
proxy.mittBus.emit("setSendColumnsChildren", resData);
};
//
@ -114,12 +116,31 @@ export default {
return item;
});
};
// tagsView columnsAsideList
const setColumnsMenuHighlight = (path) => {
state.routeSplit = path.split("/");
state.routeSplit.shift();
const routeFirst = `/${state.routeSplit[0]}`;
const currentSplitRoute = state.columnsAsideList.find(
(v) => v.path === routeFirst
);
//
setTimeout(() => {
onColumnsAsideDown(currentSplitRoute.k);
}, 0);
};
//
watch(store.state, (val) => {
if (val.routes.length === state.columnsAsideList.length) return false;
setFilterRoutes();
});
//
onMounted(() => {
setFilterRoutes();
});
//
onBeforeRouteUpdate((to) => {
setColumnsMenuHighlight(to.path);
proxy.mittBus.emit("setSendColumnsChildren", setSendChildren(to.path));
});
return {

View File

@ -15,8 +15,9 @@ import {
onMounted,
onUnmounted,
getCurrentInstance,
watch,
} from "vue";
import { useRoute, onBeforeRouteUpdate } from "vue-router";
import { useRoute } from "vue-router";
import { useStore } from "/@/store/index.ts";
import Breadcrumb from "/@/views/layout/navBars/breadcrumb/breadcrumb.vue";
import User from "/@/views/layout/navBars/breadcrumb/user.vue";
@ -95,6 +96,11 @@ export default {
});
return currentData;
};
//
watch(store.state, (val) => {
if (val.routes.length === state.menuList.length) return false;
setFilterRoutes();
});
//
onMounted(() => {
setFilterRoutes();
@ -106,13 +112,6 @@ export default {
onUnmounted(() => {
proxy.mittBus.off("getBreadcrumbIndexSetFilterRoutes");
});
//
onBeforeRouteUpdate((to) => {
proxy.mittBus.emit(
"setSendClassicChildren",
setSendClassicChildren(to.path)
);
});
return {
getThemeConfig,
setIsShowLogo,

View File

@ -81,6 +81,7 @@ export default {
};
// vuex tagsViewRoutes
const getTagsViewRoutes = () => {
state.routePath = route.path;
state.tagsViewList = [];
removeSession("tagsViewList");
state.tagsViewRoutesList = store.state.tagsViewRoutes;
@ -185,6 +186,7 @@ export default {
};
// tagsView
const onTagsClick = (v: object, k: number) => {
state.routePath = v.path;
state.tagsRefsIndex = k;
router.push(v.path);
};

View File

@ -1,7 +1,8 @@
<template>
<div class="el-menu-horizontal-warp">
<el-scrollbar @wheel.native.prevent="onElMenuHorizontalScroll" ref="elMenuHorizontalScrollRef">
<el-menu router :default-active="defaultActive" background-color="transparent" mode="horizontal">
<el-menu router :default-active="defaultActive" background-color="transparent" mode="horizontal"
@select="onHorizontalSelect">
<template v-for="val in menuList">
<el-submenu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
<template #title>
@ -90,6 +91,37 @@ export default defineComponent({
state.defaultActive = path;
}
};
//
const filterRoutesFun = (arr: Array<object>) => {
return arr
.filter((item) => !item.meta.isHide)
.map((item) => {
item = Object.assign({}, item);
if (item.children) item.children = filterRoutesFun(item.children);
return item;
});
};
//
const setSendClassicChildren = (path: string) => {
const currentPathSplit = path.split("/");
let currentData: object = {};
filterRoutesFun(store.state.routes).map((v, k) => {
if (v.path === `/${currentPathSplit[1]}`) {
v["k"] = k;
currentData["item"] = [{ ...v }];
currentData["children"] = [{ ...v }];
if (v.children) currentData["children"] = v.children;
}
});
return currentData;
};
//
const onHorizontalSelect = (path) => {
proxy.mittBus.emit(
"setSendClassicChildren",
setSendClassicChildren(path)
);
};
//
onMounted(() => {
initElMenuOffsetLeft();
@ -103,6 +135,7 @@ export default defineComponent({
return {
menuList,
onElMenuHorizontalScroll,
onHorizontalSelect,
...toRefs(state),
};
},

View File

@ -39,6 +39,7 @@ export default defineComponent({
nextTick(() => {
state.iframeLoading = true;
const iframe = document.getElementById("iframe");
if (!iframe) return false;
iframe.onload = () => {
state.iframeLoading = false;
};
@ -59,7 +60,9 @@ export default defineComponent({
});
//
onUnmounted(() => {
proxy.mittBus.off("onTagsViewRefreshRouterView");
proxy.mittBus.off("onTagsViewRefreshRouterView", () => {
console.log(1111);
});
});
return {
...toRefs(state),

View File

@ -57,9 +57,9 @@ export default defineComponent({
onBeforeMount(() => {
proxy.mittBus.on("onTagsViewRefreshRouterView", (path: string) => {
if (route.path !== path) return false;
state.refreshRouterViewKey = Math.random();
state.refreshRouterViewKey = route.path;
nextTick(() => {
state.refreshRouterViewKey = path;
state.refreshRouterViewKey = null;
});
});
});

View File

@ -1,14 +1,116 @@
<template>
<div>
limitsFrontEndBtn
<el-input v-model="val"></el-input>
<LimitsFrontEndPage />
<el-card shadow="hover" header="演示1组件方式" class="mt15">
<el-row class="mb10" style="color:#808080;">单个权限验证:value="xxx"</el-row>
<div class="flex-warp">
<Auth :value="'btn.add'">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="primary" size="small" icon="el-icon-document-add">新增
</el-button>
</div>
</div>
</Auth>
<Auth :value="'btn.edit'">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="info" size="small" icon="el-icon-edit-outline">编辑</el-button>
</div>
</div>
</Auth>
<Auth :value="'btn.del'">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="danger" size="small" icon="el-icon-delete">删除
</el-button>
</div>
</div>
</Auth>
<Auth :value="'btn.link'">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="success" size="small" icon="el-icon-link">跳转
</el-button>
</div>
</div>
</Auth>
</div>
<el-row class="mb10 mt10" style="color:#808080;">多个权限验证有满足一个则显示:value="[xxx,xxx]"</el-row>
<div class="flex-warp">
<Auths :value="['btn.addsss','btn.edit','btn.delsss','btn.linksss']">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="primary" size="small" icon="el-icon-document-add">新增
</el-button>
</div>
</div>
</Auths>
<Auths :value="['btn.add','btn.edit','btn.del','btn.link']">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="info" size="small" icon="el-icon-edit-outline">编辑</el-button>
</div>
</div>
</Auths>
<Auths :value="['btn.add','btn.edit','btn.del','btn.link']">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="danger" size="small" icon="el-icon-delete">删除
</el-button>
</div>
</div>
</Auths>
<Auths :value="['btn.add','btn.edit','btn.del','btn.link']">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="success" size="small" icon="el-icon-link">跳转
</el-button>
</div>
</div>
</Auths>
</div>
<el-row class="mb10 mt10" style="color:#808080;">多个权限验证全部满足则显示:value="[xxx,xxx]"</el-row>
<div class="flex-warp">
<AuthAll :value="['btn.add','btn.edit','btn.del','btn.link']">
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="primary" size="small" icon="el-icon-document-add">新增
</el-button>
</div>
</div>
</AuthAll>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="info" size="small" icon="el-icon-edit-outline">编辑</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="danger" size="small" icon="el-icon-delete">删除
</el-button>
</div>
</div>
<div class="flex-warp-item">
<div class="flex-warp-item-box">
<el-button type="success" size="small" icon="el-icon-link">跳转
</el-button>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script lang="ts">
import { toRefs, reactive } from "vue";
import LimitsFrontEndPage from "/@/views/limits/frontEnd/page/index.vue";
import Auth from "/@/views/components/auth/auth.vue";
import Auths from "/@/views/components/auth/auths.vue";
import AuthAll from "/@/views/components/auth/authAll.vue";
export default {
name: "limitsFrontEndBtn",
components: { LimitsFrontEndPage, Auth, Auths, AuthAll },
setup() {
const state = reactive({
val: "",
@ -18,4 +120,20 @@ export default {
};
},
};
</script>
</script>
<style scoped lang="scss">
.flex-warp {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
margin: 0 -5px;
.flex-warp-item {
padding: 5px;
.flex-warp-item-box {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@ -1,6 +1,8 @@
<template>
<div>
<el-alert :title="`当前用户权限:[${getAuthList}]`" type="success" :closable="false"></el-alert>
<el-alert title="温馨提示此权限页面代码及效果只作为演示使用若出现不可逆转的bug请尝试 `F5` 刷新页面若实际项目中非要实现此用户权限切换功能
请在切换方法 `onRadioChange` 最后面添加刷新代码 `window.location.reload()`" type="warning" :closable="false"></el-alert>
<el-alert :title="`当前用户权限:[${getAuthList}]`" type="success" :closable="false" class="mt15"></el-alert>
<el-card shadow="hover" header="切换用户演示,前端控制不同用户显示不同页面权限" class="mt15">
<el-radio-group v-model="userAuth" size="small" @change="onRadioChange">
<el-radio-button label="admin"></el-radio-button>
@ -47,16 +49,17 @@ export default {
//
const onRadioChange = () => {
resetRoute();
let defaultAuthList: Array<string> = [];
let defaultAuthPageList: Array<string> = [];
let adminAuthList: Array<string> = [
"admin",
"btn.add",
"btn.del",
"btn.edit",
"btn.link",
];
let testAuthList: Array<string> = ["test", "btn.add"];
if (state.userAuth === "admin") defaultAuthList = adminAuthList;
else defaultAuthList = testAuthList;
let testAuthList: Array<string> = ["test", "btn.add", "btn.link"];
if (state.userAuth === "admin") defaultAuthPageList = adminAuthList;
else defaultAuthPageList = testAuthList;
const userInfos = {
userName: state.userAuth,
photo:
@ -64,10 +67,11 @@ export default {
? "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg"
: "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=317673774,2961727727&fm=26&gp=0.jpg",
time: new Date().getTime(),
authList: defaultAuthList,
authPageList: defaultAuthPageList,
authBtnList: defaultAuthBtnList,
};
setSession("userInfo", userInfos);
store.dispatch("setAuths", defaultAuthList); // (vuex)
// store.dispatch("setAuths", defaultAuthPageList); // (vuex)
store.dispatch("setUserInfos", userInfos); // (vuex)
initAllFun(); //
};

View File

@ -74,8 +74,9 @@ export default defineComponent({
"btn.add",
"btn.del",
"btn.edit",
"btn.link",
];
let testAuthList: Array<string> = ["test", "btn.add"];
let testAuthList: Array<string> = ["test", "btn.add", "btn.link"];
if (state.ruleForm.userName === "admin") defaultAuthList = adminAuthList;
else defaultAuthList = testAuthList;
const userInfos = {