task-251(admin.html观感对齐): 用户管理补齐新建/编辑/角色+菜单授权弹窗(接线孤儿模块)
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import type { MenuOptionNode } from './user-menu-auth'
|
||||
import { fetchGrantableMenus } from './user-menu-auth-api'
|
||||
|
||||
const props = defineProps<{ checked?: number[] }>()
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:checked', ids: number[]): void
|
||||
(e: 'load', ok: boolean): void
|
||||
}>()
|
||||
|
||||
/** 仅暴露 el-tree 我们需要的两个方法,避免整组件类型耦合。 */
|
||||
type TreeRef = { setCheckedKeys(keys: unknown[]): void; getCheckedKeys(): unknown }
|
||||
const tree = ref<{ setCheckedKeys(keys: unknown[]): void; getCheckedKeys(): unknown } | null>(null)
|
||||
const data = ref<MenuOptionNode[]>([])
|
||||
const loaded = ref(false)
|
||||
|
||||
function applyChecked(): void {
|
||||
const el: TreeRef | null = tree.value
|
||||
if (!el) return
|
||||
const ids = Array.isArray(props.checked) ? props.checked.filter((id) => typeof id === 'number' && id > 0) : []
|
||||
el.setCheckedKeys(ids)
|
||||
}
|
||||
|
||||
function onCheck(): void {
|
||||
const el: TreeRef | null = tree.value
|
||||
if (!el) return
|
||||
const keys = el.getCheckedKeys()
|
||||
const ids = (Array.isArray(keys) ? keys : []).map((key) => Number(key)).filter((id) => id > 0)
|
||||
emit('update:checked', ids)
|
||||
}
|
||||
|
||||
async function load(): Promise<void> {
|
||||
try {
|
||||
data.value = await fetchGrantableMenus()
|
||||
loaded.value = true
|
||||
applyChecked()
|
||||
emit('load', true)
|
||||
} catch {
|
||||
loaded.value = false
|
||||
emit('load', false)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
watch(
|
||||
() => props.checked,
|
||||
() => {
|
||||
if (loaded.value) applyChecked()
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-scrollbar max-height="300px" class="user-menu-tree-scroll">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:data="data"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
check-strictly
|
||||
default-expand-all
|
||||
:props="{ label: 'name', children: 'children' }"
|
||||
@check="onCheck"
|
||||
/>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
Reference in New Issue
Block a user