| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- <script setup lang="ts">
- import { onMounted, ref, defineEmits, watch, nextTick } from "vue";
- import { getSystemRoleDeptTree } from "@/api/system/role";
- import { type CheckboxValueType } from "element-plus";
- onMounted(() => {
- getDeptList();
- console.log(model.value);
- });
- const emit = defineEmits(["update:modelValue"]);
- const deptList = ref([]);
- const getDeptList = async () => {
- let res = await getSystemRoleDeptTree("2");
- deptList.value = res.depts;
- };
- const model = defineModel();
- watch(
- model,
- (value: number[]) => {
- nextTick(() => {
- setCheckedKeys(value, true);
- const allKeys = getAllKeys(deptList.value);
- menuNodeAll.value = value.length === allKeys.length;
- isIndeterminate.value = value.length > 0 && value.length < allKeys.length;
- });
- },
- { immediate: true, deep: true }
- );
- const menuRef = ref(null);
- const menuCheckStrictly = ref(true);
- const menuNodeAll = ref(false);
- const menuExpand = ref(false);
- const isIndeterminate = ref(false);
- const handleCheckedTreeExpand = (value: CheckboxValueType) => {
- // 递归展开
- for (let i = 0; i < deptList.value.length; i++) {
- menuRef.value.store.nodesMap[deptList.value[i].id].expanded = value;
- }
- };
- const handleCheckedTreeNodeAll = (value: CheckboxValueType) => {
- menuRef.value.setCheckedNodes(value ? deptList.value : []);
- isIndeterminate.value = false;
- const allKeys = getAllKeys(deptList.value);
- model.value = value ? allKeys : [];
- console.log(model.value);
- console.log(menuNodeAll.value);
- };
- const handleTreeCheck = (_: any, checkedState: any) => {
- const allKeys = getAllKeys(deptList.value);
- const checkedCount = checkedState.checkedKeys.length;
- menuNodeAll.value = checkedCount === allKeys.length;
- isIndeterminate.value = checkedCount > 0 && checkedCount < allKeys.length;
- model.value = checkedState.checkedKeys;
- emit("update:modelValue", checkedState.checkedKeys);
- };
- // 递归获取所有节点key
- const getAllKeys = (data: any) => {
- return data.reduce((keys: any, node: any) => {
- keys.push(node.id);
- if (node.children && menuCheckStrictly) {
- keys.push(...getAllKeys(node.children));
- }
- return keys;
- }, []);
- };
- const setCheckedKeys = (keys: number[], leafOnly: boolean) => {
- return menuRef.value.setCheckedKeys(keys, leafOnly);
- };
- </script>
- <template>
- <div style="width: 100%">
- <el-row type="flex" justify="space-between" align="middle">
- <el-col :span="4">
- <el-checkbox
- v-model="menuExpand"
- @change="handleCheckedTreeExpand($event)"
- >全部展开/折叠
- </el-checkbox>
- </el-col>
- <el-col :span="4">
- <el-checkbox
- v-model="menuNodeAll"
- :indeterminate="isIndeterminate"
- @change="handleCheckedTreeNodeAll($event)"
- >全选/全不选
- </el-checkbox>
- </el-col>
- <el-col :span="4">
- <el-checkbox v-model="menuCheckStrictly">级联下级 </el-checkbox>
- </el-col>
- </el-row>
- <el-tree
- ref="menuRef"
- class="tree-border"
- :data="deptList"
- show-checkbox
- node-key="id"
- empty-text="加载中,请稍后"
- :check-strictly="!menuCheckStrictly"
- @check="handleTreeCheck"
- />
- </div>
- </template>
- <style scoped lang="scss">
- /* tree border */
- .tree-border {
- width: 100%;
- margin-top: 5px;
- border: 1px solid #e5e6e7;
- background: #ffffff none;
- border-radius: 4px;
- }
- </style>
|