| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- <script setup lang="ts">
- import {onMounted, ref, defineEmits, watch, nextTick} from "vue";
- import {getMenuListTree} from "@/api/system/menu";
- import {type CheckboxValueType} from 'element-plus'
- onMounted(() => {
- getMenuList();
- console.log(model.value)
- })
- const emit = defineEmits(['update:modelValue'])
- const menuList = ref([]);
- const getMenuList = async () => {
- let res = await getMenuListTree();
- menuList.value = res.data;
- }
- const model = defineModel()
- watch(model, (value: number[]) => {
- nextTick(() => {
- setCheckedKeys(value, true)
- const allKeys = getAllKeys(menuList.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 < menuList.value.length; i++) {
- menuRef.value.store.nodesMap[menuList.value[i].id].expanded = value;
- }
- }
- const handleCheckedTreeNodeAll = (value: CheckboxValueType) => {
- menuRef.value.setCheckedNodes(value ? menuList.value : []);
- isIndeterminate.value = false;
- const allKeys = getAllKeys(menuList.value);
- model.value = value ? allKeys : [];
- console.log(model.value)
- console.log(menuNodeAll.value)
- }
- const handleTreeCheck = (_: any, checkedState: any) => {
- const allKeys = getAllKeys(menuList.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 :indeterminate="isIndeterminate" v-model="menuNodeAll"
- @change="handleCheckedTreeNodeAll($event)">全选/全不选
- </el-checkbox>
- </el-col>
- <el-col :span="4">
- <el-checkbox v-model="menuCheckStrictly">级联下级
- </el-checkbox>
- </el-col>
- </el-row>
- <el-tree class="tree-border" :data="menuList" show-checkbox ref="menuRef" node-key="id"
- empty-text="加载中,请稍后"
- :check-strictly="!menuCheckStrictly" @check="handleTreeCheck">
- </el-tree>
- </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>
|