效果
点击分配角色后,弹窗,显示用户目前的权限,并且在下拉菜单里可以多选
分配角色弹窗组件跟之前的用户列表差不多
<template>
<el-dialog v-model="visible" title="分配角色" :before-close="close">
<el-form :model="form">
<el-form-item >
<el-select multiple v-model="roles" placeholder="请分配角色权限">
<el-option v-for="role in form.roleLists" :label="role.name" :value="role.id" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="close">确认</el-button>
<el-button type="primary" @click="updateRole">
取消
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import {defineProps,reactive,ref,watch} from 'vue'
type NU = number | undefined;
const roles = ref<NU[]>([]);
const props = defineProps<{
visible: boolean;
form: AdminRoleFormData
}>()
const emits = defineEmits<{
(event: 'close'):void
}>();
//监听
watch(() => props.form.userRoles,() => {
if(props.form.userRoles){
roles.value = props.form.userRoles.map(item => item.id)
}
})
const close = () => {
emits('close')
}
const updateRole = () => {
close();
}
</script>
<EditRole :visible="roleVisible" :form="roleData" @close="closeRoleDialog"></EditRole>
import { getAdminList,getRoleListAll,getAdminRoleById } from '../../request/api'
const state = reactive<{ tableData: {}[]; visible: boolean; rowData: {}; roleVisible: boolean;roleData: AdminRoleFormData }>({
tableData: [],
visible: false,
rowData: {},
roleVisible: false,
roleData: {}
})
const { tableData, visible, rowData, roleVisible, roleData } = toRefs(state);
//获取所有角色
getRoleListAll().then(res => {
if(res.code === 200){
roleData.value.roleLists = res.data;
}
})
//分配角色事件点击
const allocRole = (id: number) => {
getAdminRoleById(id).then(res => {
if(res.code === 200){
roleVisible.value= true;
roleData.value.userRoles = res.data;
}
})
}
//隐藏分配角色弹框
const closeRoleDialog = () => {
roleVisible.value = false;
}
难点:分配角色的弹窗组件需要第一时间显示用户已有角色
<el-form :model="form">
<el-form-item >
<el-select multiple v-model="roles" placeholder="请分配角色权限">
<el-option v-for="role in form.roleLists" :label="role.name" :value="role.id" />
</el-select>
</el-form-item>
</el-form>
v-model的数据可以直接展示,因此watch监听到父组件传过来的数据后,马上让roles接受
watch(() => props.form.userRoles,() => {
if(props.form.userRoles){
roles.value = props.form.userRoles.map(item => item.id)
}
})
监听之后,只需要返回id即可,因为options的value绑定的也是id,相当于key一致
接口类型依然需要重视
interface AdminRoleFormData {
userRoles?: RoleObjItf[];
roleLists?: RoleObjItf[];
}
interface RoleObjItf {
id?: number;
name?: string;
}
//获取所有角色
export const getRoleListAll = ():PromiseRes<RoleObjItf[]> => request.get('/role/listAll')
//根据用户id获取角色
export const getAdminRoleById = (id:number):PromiseRes<RoleObjItf[]> => request.get('/admin/role/'+id)
分配角色弹窗确认事件
先写接口
post接口发送params参数,需要放在第三个参数位置;第二个参数为请求体
//分配用户角色
export const updateAdminRole = (data: {adminId: number| undefined;roleIds: string}):PromiseRes => request.post('/admin/role/update',null,{params: data})
import {updateAdminRole} from '../../../request/api'
const updateRole = () => {
updateAdminRole({adminId :props.form.adminId,roleIds:roles.value.join(',')}).then(res => {
if(res.code === 200){
close();
}
})
}
这里使用数组拼接转换为字符串
如果不希望手动转,也可以使用第三方库qs
这样可以把参数放第二位,且自动转换数组内容
roleIds可以直接传数组了