2021-04-02 19:00:16 +08:00

122 lines
2.0 KiB
Vue

<template>
<div class="cl-menu-perms">
<el-cascader
v-model="value"
separator=":"
clearable
filterable
:options="options"
:props="{ multiple: true }"
@change="onChange"
/>
</div>
</template>
<script lang="ts">
import { defineComponent, inject, ref, watch } from "vue";
export default defineComponent({
name: "cl-menu-perms",
props: {
modelValue: {
type: String,
default: ""
}
},
emits: ["update:modelValue"],
setup(props, { emit }) {
const service = inject<any>("service");
// 绑定值
const value = ref<any[]>([]);
// 权限列表
const options = ref<any[]>([]);
// 监听改变
function onChange(row: any) {
emit("update:modelValue", row.map((e: any) => e.join(":")).join(","));
}
// 解析权限
(function parsePerm() {
const list: any[] = [];
let perms: any[] = [];
const flat = (obj: any) => {
for (const i in obj) {
const { permission } = obj[i];
if (permission) {
perms = [...perms, Object.values(permission)].flat();
} else {
flat(obj[i]);
}
}
};
flat(service);
perms
.filter((e) => e.includes(":"))
.map((e) => e.split(":"))
.forEach((arr) => {
const col = (i: number, d: any[]) => {
const key = arr[i];
const index = d.findIndex((e: any) => e.label == key);
if (index >= 0) {
col(i + 1, d[index].children);
} else {
const isLast = i == arr.length - 1;
d.push({
label: key,
value: key,
children: isLast ? null : []
});
if (!isLast) {
col(i + 1, d[d.length - 1].children || []);
}
}
};
col(0, list);
});
options.value = list;
})();
// 监听值
watch(
() => props.modelValue,
(val: string) => {
value.value = val ? val.split(",").map((e: string) => e.split(":")) : [];
},
{
immediate: true
}
);
return {
value,
options,
onChange
};
}
});
</script>
<style lang="scss">
.cl-menu-perms {
.el-cascader {
width: 100%;
}
}
</style>