弹框组件el-tree+vue3必坑指南

点击查看代码
<script setup lang="ts">
import { ref, reactive, computed, onBeforeMount } from 'vue'
import { menuPage, addRole, getRole, updateRole } from '@/utils/api/role'
import { ElTree } from 'element-plus'
import type Node from 'element-plus/es/components/tree/src/model/node'
interface Isex {
  createBy: String
  createTime: Number
  id: String
  remark: String
  sort: Number
  k: String
  v: String
  typeId: String
  updateBy: String
  updateTime: Number
}
let emit = defineEmits()
let props = defineProps<{
  id?: string
  show: boolean
}>()
const id = ref(props.id)
const formRef = ref(null)
let form = reactive({
  roleName: '',
  rolePerm: '',
  enabled: 1,
  descript: '',
})

let _show = computed({
  get() {
    return props.show
  },
  set(value) {
    emit('update:show', value)
  },
})
//控制菜单树
const permission = reactive({
  openAll: false,
  selectAll: false,
  linkage: true,
  treeList: [],
})
const treeRef = ref<InstanceType<typeof ElTree>>()
const onCancel = () => {
  _show.value = false
}
const defaultProps = {
  children: 'children',
  label: 'name',
}
const toggleTreeCollapse = (value) => {
  const nodes = treeRef.value.store.nodesMap
  for (let i in nodes) {
    nodes[i].expanded = value
  }
}
const toggleTreeChecked = (value) => {
  if (value) {
    console.log('permission.linkage', permission.linkage)
    permission.treeList.map((m) => {
      treeRef.value?.setChecked(m, true, true)
    })
  } else {
    treeRef.value?.setCheckedKeys([])
  }
}
const toggleTreeCheckedFs = (value) => {
  permission.linkage = value
}
const normalizeData = (list) => {
  // parentId 和 id 有联系 parentId为-1是一级列表
  let newArr = []
  let mapObj = {}
  list.forEach((m) => {
    mapObj[m.id] = m
  })
  list.forEach((mn) => {
    if (mn.id === '-1') {
      return newArr.push(mn)
    }
    const parObj = mapObj[mn.parentId]
    if (parObj) {
      parObj.children.push(mn)
    } else {
      newArr.push(mn)
    }
  })
  return newArr
}
onBeforeMount(async () => {
  let {
    data: { records },
  } = await menuPage({ current: 1, size: 1000 })
  // permission.treeList = records
  // 数据处理tree
  let treeLists = normalizeData(records)
  permission.treeList = treeLists
})
</script>

<template>
  <div class="roleEditor-page">
    <el-dialog
      :modelValue="_show"
      width="600px"
      :title="id ? '修改' : '新增'"
      :append-to-body="true"
      :destroy-on-close="true"
    >
      <el-form v-model="form" ref="formRef">
        <el-form-item label="角色名称" prop="roleName">
          <el-input placeholder="请输入角色名称" v-model="form.roleName" />
        </el-form-item>

        <el-form-item label="权限字符" prop="rolePerm">
          <el-input placeholder="请输入权限字符" v-model="form.rolePerm" />
        </el-form-item>
        <el-form-item label="状态" prop="rolePerm">
          <el-radio-group v-model="form.enabled">
            <el-radio :label="1">启用</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- start -->
        <el-form-item label="菜单权限">
          <div class="checkB">
            <el-checkbox
              v-model="permission.openAll"
              @change="toggleTreeCollapse"
            >
              展开/折叠
            </el-checkbox>

            <el-checkbox
              v-model="permission.selectAll"
              @change="toggleTreeChecked"
              >全选/全不选</el-checkbox
            >

            <el-checkbox
              v-model="permission.linkage"
              @change="toggleTreeCheckedFs"
              >父子(联动/不联动)
            </el-checkbox>
            <el-tree
              ref="treeRef"
              :data="permission.treeList"
              :check-strictly="!permission.linkage"
              show-checkbox
              node-key="id"
              :props="defaultProps"
              class="treeB"
            />
          </div>
        </el-form-item>
        <!-- end -->
        <el-form-item label="备注" prop="descript">
          <el-input
            type="textarea"
            placeholder="请输入内容"
            v-model="form.descript"
            :maxlength="200"
            show-word-limit
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="onCancel">取消</el-button>
          <el-button type="primary">确认 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.checkB {
  width: 100%;
}
.treeB {
  margin-top: 0.5rem;
  background-color: #fff;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}
</style>

posted @   jialiangzai  阅读(180)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

喜欢请打赏

扫描二维码打赏

微信打赏

点击右上角即可分享
微信分享提示