需求是利用element-plusd的组件标签tag去实现增加部门的种类,效果图如下:
①在系统设置中添加/删减对应的部门
②在部门下拉框中弹出自己设置的部门
实现的思路是:通过系统设置中的部门设置增删部门,更新数据库中的部门设置字段,再通过获取数据库中的数据渲染至下拉框中
实现的难点在于:tag标签的数据类型是一个数组类型
例如:["总裁办","产品部","销售部","组织部"]
这里需要注意的是上传到数据库中,数组需为字符串形式
然后是下拉框的数据类型是数组包裹着对象,例如下面所示:
const options = [{value: 'Option1',label: 'Option1',},{value: 'Option2',label: 'Option2',},
]
所以需要把数组类型转换成这种数组包裹着对象的类型
首先是tag的标签部分的代码:
template部分
<div class="department-set"><span>部门设置</span><!-- disable-transitions是否禁用渐变动画 --><!-- closable是否可关闭 --><!-- close关闭 Tag 时触发的事件 --><el-tag v-for="tag in dynamicTags" :key="tag" class="mx-1" closable:disable-transitions="false" @close="handleClose(tag)">{{ tag }}</el-tag>el-input v-if="inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20"size="small" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" /><el-button v-else class="button-new-tag ml-1" size="small" @click="showInput">+ 添加部门组织</el-button>
</div>
script部分 (组合式setup Ts)
// 其他设置 部门标签
const inputValue = ref('')
// dynamicTags 即为tag中的数据
const dynamicTags = ref()
// element-plus中自带的
const inputVisible = ref(false)
// element-plus中自带的
const InputRef = ref<InstanceType<typeof ElInput>>()// 删减部门
const handleClose = async (tag : string) => {// splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。// 第一个参数为位置,第二个为删除的个数// setdepartment为更新tag的接口// 因为dynamicTags里面的数据是代理的,所以传参的时候需要变为原始数据// JSON.stringify把参数变为字符串进行传参到接口dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1)const res = await setdepartment(JSON.stringify(toRaw(dynamicTags.value)))// res为后端设置的返回数据if (res == '设置成功') {ElMessage({message: '移除部门成功',type: 'success',})} else {ElMessage.error('移除部门失败,请检查网络是否通畅')}
}// 显示输入内容 组件自带的参数
const showInput = () => {
inputVisible.value = truenextTick(() => {InputRef.value!.input!.focus()})
}// 添加部门
const handleInputConfirm = async () => {if (inputValue.value) {dynamicTags.value.push(inputValue.value)// 再次提醒:从Reactive或Ref中得到原始数据// 把数组转换成json格式const res = await setdepartment(JSON.stringify(toRaw(dynamicTags.value)))if (res == '设置成功') {ElMessage({message: '添加部门成功',type: 'success',})}else {ElMessage.error('添加部门失败,请检查网络是否通畅')}}inputVisible.value = falseinputValue.value = ''
}
然后是用户界面下拉框的实现逻辑:
template部分
<el-select v-model="department"
class="m-2"
clearable
placeholder="选择部门进行筛选"
@change='searchOfDepartment'
ar='clearSelect'>
<el-optionv-for="item in options":key="item.value":label="item.value":value="item.value"/>
</el-select>
script部分 (组合式setup TS)
// 部门数据
const options = ref([])
/ 选中的部门
const department = ref()
// 获取部门数据
const getdepartmentlist = async () => {const res = await getdepartment()const data = []// 把数组的每一项都取出来,变成一个单独的对象,再把这个对象push进新数组
// 不要把obj放在for循环外,不然输出的数组内容都是最后一个数据,初级知识这里不再叙述for(let i=0;i<res.length;i++){let obj = {value:res[i]}data.push(obj)}options.value = data
}
// 调用上面的函数
getdepartmentlist()
涉及的三个接口如下(前端部分):
// 用户所属部门设置
export const setdepartment = tags => {return instance({url: '/set/setDepartment',method: 'POST',data: {tags}})
}// 获取所有部门
export const getdepartment = () => {return instance({url: '/set/getDepartment',method: 'POST',})
}// 根据部门去筛选用户
export const searchofdepartment = (department) => {return instance({url: '/set/departmentUser',method: 'POST',data:{department}})
}
涉及的三个接口如下(后端部分):
// 用户所属部门设置
exports.setDepartment = (req, res) => {// res.send(req.body.tags)const userinfo = req.bodyconst name = '部门设置'const sql = 'update setting set set_value = ? where set_name = ?'db.query(sql, [userinfo.tags, name], (err, result) => {if (err) return res.cc(err)res.send('设置成功')})
}// 设置获取所有部门
exports.getDepartment = (req, res) => {const userinfo = req.bodyconst name = '部门设置'const sql = 'select set_value from setting where set_name = ? 'db.query(sql, name, (err, result) => {if (err) return res.cc(err)res.send(result[0].set_value)})
}// 根据部门去筛选用户
exports.departmentUser = (req, res) => {const userinfo = req.bodyconst identity = '用户'const sql = 'select * from users where department = ? and identity = ? 'db.query(sql, [userinfo.department, identity], (err, result) => {if (err) return res.cc(err)res.send(result)})
}
数据库字段:
一个关键点是在设计数据库之处就需要把部门设置
添加到set_name
的value
中,后面需要更改的时候在接口中指定改部门设置
即可