【Vue3】el-checkbox-group实现权限配置和应用

news2024/11/28 3:44:07

一. 需求

  1. 针对不同等级的用户,配置不同的可见项

  2. 配置效果如下
    (1)新增,获取数据列表在这里插入图片描述
    (2)编辑,回显数据列表
    在这里插入图片描述

  3. 应用效果如下
    (1)父级配置
    在这里插入图片描述
    (2)子级配置
    在这里插入图片描述

二. 数据格式

  1. 普通用户列表、vip用户列表、svip用户列表 共用一个List
// type == 0 父:级可配置
// type == 2 :父级必然存在 
// type == 1 :type==2的 子级(若有的必然存在,可通过name进行筛选)
List:[
	{
		id: 1,
		children:null,
		createTime: null,
		name: "par1",
		value: "父1",
		isDel: 0,
		sort: 1,
		type: 0,
	},
	{
		id: 2,
		children:null,
		createTime: null,
		name: "par2",
		value: "父2",
		isDel: 0,
		sort: 2,
		type: 0,
	},
	{
		id: 3,
		children:null,
		createTime: null,
		name: "par3",
		value: "父3",
		isDel: 0,
		sort: 3,
		type: 0,
	},
	{
		id: 4,
		children:null,
		createTime: null,
		name: "par4",
		value: "父4",
		isDel: 0,
		sort: 4,
		type: 0,
	},
	{
		id: 5,
		children:null,
		createTime: null,
		name: "par5",
		value: "父5",
		isDel: 0,
		sort: 5,
		type: 0,
	},
	{
		id: 6,
		children:[
			{
				id: 7,
				children:null,
				createTime: null,
				name: "child1",
				value: "子1",
				isDel: 0,
				sort: 1,
				type: 1,
			},
			{
				id: 8,
				children:null,
				createTime: null,
				name: "child2",
				value: "子2",
				isDel: 0,
				sort: 2,
				type: 1,
			},
			{
				id: 9,
				children:null,
				createTime: null,
				name: "child3",
				value: "子3",
				isDel: 0,
				sort: 3,
				type: 1,
			},
			{
				id: 10,
				children:null,
				createTime: null,
				name: "child4",
				value: "子4",
				isDel: 0,
				sort: 4,
				type: 1,
			},
			{
				id: 11,
				children:null,
				createTime: null,
				name: "child5",
				value: "子5",
				isDel: 0,
				sort: 5,
				type: 1,
			},
			{
				id: 12,
				children:null,
				createTime: null,
				name: "child6",
				value: "子6",
				isDel: 0,
				sort: 6,
				type: 1,
			},
			{
				id: 13,
				children:null,
				createTime: null,
				name: "child7",
				value: "子7",
				isDel: 0,
				sort: 7,
				type: 1,
			},
		],
		createTime: null,
		name: "par6",
		value: "父6",
		isDel: 0,
		sort: 6,
		type: 2,
	},
]
  1. 思路:调用接口获取List,将同一个List 分别赋值给三个不同的数组。

三. 实现

  1. 数据获取并渲染 及 回显 功能
<template>
  <div>
    <el-form ref="detailRef" :model="form" :rules="rules" label-width="140px">
        <el-form-item label="普通用户" prop="ordinaryUser">
          <el-checkbox-group v-model="form.ordinaryUser">
            <el-checkbox v-for="item in ordinaryUser" v-show="item.type == 0" :key="item.id"
              class="check-box"
              :label="item.name"
              >{{ item.value }}</el-checkbox
            >
            <div>
              <el-checkbox v-for="item in ordinaryUser" v-show="item.type == 1" :key="item.id"
                class="check-box"
                :label="item.name"
                >{{ item.value }}</el-checkbox
              >
            </div>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="VIP用户" prop="vipUser">
          <el-checkbox-group v-model="form.vipUser">
            <el-checkbox v-for="item in vipUser" v-show="item.type == 0" :key="item.id"
              class="check-box"
              :label="item.name"
              >{{ item.value }}</el-checkbox
            >
            <div>
              <el-checkbox v-for="item in vipUser" v-show="item.type == 1" :key="item.id"
                class="check-box"
                :label="item.name"
                >{{ item.value }}</el-checkbox
              >
            </div>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="SVIP用户" prop="svipUser">
          <el-checkbox-group v-model="form.svipUser">
            <el-checkbox v-for="item in svipUser" v-show="item.type == 0" :key="item.id"
              class="check-box"
              :label="item.name"
              >{{ item.value }}</el-checkbox
            >
            <div>
              <el-checkbox v-for="item in vipUser" v-show="item.type == 1" :key="item.id"
                class="check-box"
                :label="item.name"
                >{{ item.value }}</el-checkbox
              >
            </div>
          </el-checkbox-group>
        </el-form-item>
    </el-form>
    <div>
      <el-button @click="handleClick">取 消</el-button>
      <el-button type="primary" @click="submitForm">确 认</el-button>
    </div>
  </div>
</template>
<script setup name="ManageMenu">
import { getList,update } from '@/api/xxx/xxx'
import { getConfigList } from '@/api/xxx/xxxConfig'
import { reactive } from '@vue/reactivity'
import { ref } from 'vue'

const { proxy } = getCurrentInstance()

const route = useRoute()
const configId = route.params.id //  通过路由获取到 配置id

const ordinaryUser = ref([]) // 普通用户
const vipUser = ref([]) // vip用户
const svipUser = ref([]) // svip用户
const selectStartLevel = reactive([]) // 当前选中项
const allStartLevel = ref([]) // 全部数据

const selectOrdinaryUser = ref([]) // 当前选中的普通用户可见项
const selectVipUser = ref([]) // 当前选中的vip用户可见项
const selectSVipUser = ref([]) // 当前选中的svip用户可见

const data = reactive({
  form: {},
  rules: {
    ordinaryUser: [{ type: 'array', required: true, message: '必填', trigger: ['blur'] }],
    vipUser: [{ type: 'array', required: true, message: '必填', trigger: ['blur'] }],
    svipUser: [{ type: 'array', required: true, message: '必填', trigger: ['blur'] }]
  }
})

// 重置表单
const reset = () => {
  form.value = {
    id: null,
    ordinaryUser: [],
    vipUser: [],
    svipUser: [],
    List: [] // 给后端传/回显数据的数组
  }
  proxy.resetForm('detailRef')
}

/**
 * 初始化列表数据
 */
onMounted(() => {
  reset()
  getCList()
  // 数据回显
  if (configId != null) {
   getActivityManageListDetails ({ configId: Number(configId) }).then(res => {
      if (res.code === 200) {
        form.value = res.data
        form.value.ordinaryUser = form.value.List
          .filter(item => item.rankConfig === 3 && item.configFlag === 1)
          .map(item => item.name)
        form.value.vipUser = form.value.List
          .filter(item => item.rankConfig === 2 && item.configFlag === 1)
          .map(item => item.name)
        form.value.svipUser = form.value.List
          .filter(item => item.rankConfig === 1 && item.configFlag === 1)
          .map(item => item.name)
      }
    })
  }
})

/**
 * 扁平化配置项数据
 */
const getCList = () => {
   // 获取配置项 并并扁平化,同时设置等级
  getConfigList().then(res => {
  	// res.data 数据格式就是 上述List
    ordinaryUser.value = treeToArray(res.data, 3) // 三级
    vipUser.value = treeToArray(res.data, 2) // 二级
    svipUser.value = treeToArray(res.data, 1) // 一级
    // 将扁平化的数据,整理放到一个数组中
    allStartLevel.value = [...ordinaryUser.value, ...vipUser.value, ...svipUser.value]
    // 过滤到type != 2 的数据 type=2,这一项因为需求在代码中写死了,时时刻刻存在所以要筛查掉
    allStartLevel.value = allStartLevel.value.filter(item => item.type !== 2)
  })
}

/**
 * 点击确定
 */
const submitForm = () => {
  selectOrdinaryUser.value = form.value.ordinaryUser.map(item => ({ rankConfig: 3, dictEnglishName: item }))
  selectVipUser.value = form.value.vipUser.map(item => ({ rankConfig: 2, dictEnglishName: item }))
  selectSVipUser.value = form.value.svipUser.map(item => ({ rankConfig: 1, dictEnglishName: item }))
  // 当前选中项
  selectStartLevel.value = [...selectOrdinaryUser.value, ...selectVipUser.value, ...selectSVipUser.value]
  // 设置选中项对应的星级 是否选中
  allStartLevel.value.forEach(item => {
    item.configId = item.id
    selectStartLevel.value.forEach(val => {
      if (item.rankConfig === val.rankConfig && item.name === val.name) {
        item.configFlag = 1
      }
    })
  })
  // 设置级别权限
 form.value.List = allStartLevel.value
  proxy.$refs['detailRef'].validate(valid => {
    if (valid) {
      console.log(...form.value, '校验成功了吗');
      if (configId != null) {
         update({ id: Number(configId), ...form.value }).then(res => {
           if (res.code === 200) {
             proxy.$modal.msgSuccess('编辑成功')
             handleClick()
             reset()
           }
         })
       } else{
         update({ id: 0, ...form.value }).then(res => {
           if (res.code === 200) {
             proxy.$modal.msgSuccess('新增成功')
             handleClick()
             reset()
           }
         })
       }
    }
  })
}

/**
 * 弹窗取消
 */
const handleClick = async () => {
  console.log('弹窗取消')
}

/**
 * 数组扁平化(reduce)
 */
const treeToArray = (tree, rankConfig) => {
  return tree.reduce((res, item) => {
    const { children, ...i } = item
    i.rankConfig = rankConfig
    i.configFlag = 0
    return res.concat(i, children && children.length ? treeToArray(children, rankConfig) : [])
  }, [])
}
</script>

<style scoped>
.check-box{
  width:90px
}
</style>
  1. 权限的应用(此处只处理父级)
<template>
   <el-tabs v-model="activeName" type="card" style="max-width: 100%" @tab-change="handleClick">
      <el-tab-pane v-for="item in leftData" :key="item.id" :label="item.value" :name="item.name">
         <component :is="allLeftCompontents[item.name]" :dataDetail="dataDetail"></component>
      </el-tab-pane>
   </el-tabs>
</template>
<script setup>
import Parent1 from '@/views/xxx/parent1'
import Parent2 from '@/views/xxx/parent2'
import Parent3 from '@/views/xxx/parent3'
import Parent4 from '@/views/xxx/parent4'
import Parent5 from '@/views/xxx/parent5'
import Parent6 from '@/views/xxx/parent6'
import { getApplyDetail } from "@/api/xxx"
import { getConfigListByConfigId } from "@/api/xxx"


const route = useRoute()
const id = route.params.id // 路由 获取id
const leftData = ref([]) // 配置数据项
const currentTab = ref('') // 当前选中tab项
const activeName = ref('') // 当前选中tab的名称
const dataDetail = reactive({}) // 获取详情

const allLeftCompontents = {
  par1: markRaw(Parent1),
  par2: markRaw(Parent2),
  par3: markRaw(Parent3),
  par4: markRaw(Parent4),
  par5: markRaw(Parent5),
  par6: markRaw(Parent6)
}

onMounted(() => {
  // 获取详情
  getApplyDetail({ id: id }).then(res => {
    if (res.code === 200) {
    	dataDetail.configId = res.data.configId
    	dataDetail.level = res.data.level
        // 获取等级权限
        getSatReviewConfigList()
    }
  })
})

/**
 * 获取配置项
 */
const getSatReviewConfigList = () => {
   getConfigListByConfigId({configId:dataDetail.configId , rankConfig: dataDetail.level}).then(result => {
          leftData.value = result.data
          // 初始加载第一个tab
          activeName.value = leftData.value[0].name
          handleClick(activeName.value)
      })
}

/**
 * 点击切换标签项
 */
const handleClick = (val) => {
  currentTab.value = val
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1560533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode90. 子集 II

去重逻辑&#xff1a; 关键是画出递归树&#xff01;当我们即将进入第二个2的递归的时候&#xff0c;发现isVisit数组是100&#xff0c;也就是说这俩重复的数是False&#xff0c;并且这俩在nums值相同&#xff0c;所以写出去重逻辑&#xff01; class Solution { public:vector…

2024-2028年中国导电滑环市场行情及未来发展前景研究报告

导电滑环应用领域广泛 全球市场将保持增长趋势 导电滑环又称为集流环、集电环、导电环&#xff0c;是一种电气连接器件&#xff0c;用于在旋转部件和静止部件之间传输电能信号。导电滑环避免了传统导线在旋转中存在的磨损和扭伤&#xff0c;可提高机器运转效率和稳定性&#xf…

美易官方:通胀持续降温,美联储可能在6月份降息

近期&#xff0c;LPL首席经济学家在接受采访时表示&#xff0c;通胀持续降温&#xff0c;美联储可能在6月份降息。这一消息引起了市场的广泛关注和讨论。通胀一直是全球经济面临的难题之一&#xff0c;而美联储的货币政策也一直是市场关注的焦点。那么&#xff0c;通胀降温和美…

Discord绑VISA卡教程

Discord 是由美国 Discord Inc. 公司所开发的一款专为社群设计的免费网络实时通话软件与数字发行平台&#xff0c;主要针对游戏玩家、教育人士、朋友及商业人士&#xff0c;用户之间可以在软件的聊天频道通过讯息、图片、视频和音频进行交流 下面进行实际操作 1、登录discord …

【A-013】基于SSH的共享单车管理系统/共享单车出租系统

【A-013】基于SSH的共享单车管理系统/共享单车出租系统 开发环境&#xff1a; Eclipse/MyEclipse、Tomcat8、Jdk1.8 数据库&#xff1a; MySQL 适用于&#xff1a; 课程设计&#xff0c;毕业设计&#xff0c;学习等等 系统介绍&#xff1a; 基于SSH开发的共享单车管理系统/…

新质生产力:1核心,2摆脱,3关键,3因素,3特征;3要素,3措施

引言 新质生产力是指以科技创新为核心驱动力&#xff0c;通过提高全要素生产率、推动产业升级和转型&#xff0c;实现经济高质量发展的能力和水平。在当今全球经济竞争日趋激烈的背景下&#xff0c;新质生产力成为各国竞争力的关键之一&#xff0c;对于实现经济可持续发展、提…

CAN总线系列二:时序以及数据帧分析

由于CAN总线是异步的&#xff0c;也就是没有时钟线&#xff0c;像串口那样设置好波特率然后进行通信。因此使得其协议时序就很重要。 一、位时序 1、时序简介 为了实现位同步&#xff0c; CAN协议把每一个数据位的时序分解成SS段、 PTS段、PBS1段、 PBS2段&#xff0c;这四段…

多区域数据交换时 哪种方案可以做到便捷又可靠?

很多企业在异地都会建立分支机构&#xff0c;比如跨国企业在国外建设分公司&#xff0c;金融机构全国各地都有多级分支机构和网点&#xff0c;集团型企业会设立多家子公司&#xff0c;等等。所以这类企业都会面临多区域文件交换的场景。 多区域文件交换的场景主要包括以下几种&…

Kubernetes之Projected Volume

目录 四种Projected Volume Secret 使用方法 应用场景 示例 ConfigMap 使用方法 应用场景 示例 Downward API 使用方法 应用场景 示例 ServiceAccountToken 使用方法 应用场景 示例 在 Kubernetes 中,有几类特殊的 Volume,它们存在的意义不是为了存放容器里的…

振弦采集仪在桥梁工程监测中的优势与实践案例

振弦采集仪在桥梁工程监测中的优势与实践案例 在桥梁工程监测中&#xff0c;振弦采集仪是一种常用的监测设备。它的主要功能是通过采集桥梁振动信号&#xff0c;实时监测桥梁的结构健康状态。与传统的监测方法相比&#xff0c;振弦采集仪具有一些明显的优势&#xff0c;下面将…

docker:在ubuntu中运行docker容器

前言 1 本笔记本电脑运行的ubuntu20.04系统 2 docker运行在ubuntu20.04系统 3 docker镜像使用的是ubuntu18.04&#xff0c;这样拉的 docker pull ubuntu:18.04 4 docker容器中运行的是ubuntu18.04的系统&#xff0c;嗯就是严谨 5 这纯粹是学习笔记&#xff0c;实际上没啥价值。…

【MySQL】DQL-分组查询-语法&where与having的区别&注意事项&可cv例题语句

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

数据结构初阶:算法的时间复杂度和空间复杂度

什么是数据结构&#xff1f; 数据结构 (Data Structure) 是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的 数据元素的集合。 什么是算法&#xff1f; 算法 (Algorithm): 就是定义良好的计算过程&#xff0c;他取一个或一组的值为输入&#xff0c…

DSSS-UQPSK学习笔记

文章目录 非平衡四相键控-直接序列扩频&#xff08;UQPSK-DSSS&#xff09;信号因其能同时传输两路不同功率、不同速率信号的特点&#xff0c;在需要图象和数据综合业务传输的领域得到了广泛应用。 系统信号的调制方式为非平衡四相键控&#xff08;Unbalanced Quadrature Phase…

【uC/OS-III篇】uC/OS-III 移植到 STM32 简明教程

uC/OS-III 移植到 STM32 简明教程 一、uC/OS-III 介绍 二、获取UCOS-III源码 三、建立项目工程 四、解决工程编译报错 五、修改项目文件 下一篇博客&#xff1a; 【uC/OS-III篇】uC/OS-III 创建第一个任务&#xff08;For STM32&#xff09; 移植后的工程自取方式&#xf…

磐启/PAN7030/2.4GHz 无线收发SOC芯片/ESSOP10/SOP16

1 概述 PAN7030 是一款集成 8 位 OTP MCU 和 2.4GHz 无线收发电路芯片&#xff0c;适合应用于玩具小车、 遥控器等领域。 PAN7030 内置 8 位 OTP MCU&#xff0c;包括 1.25KW 的程序存储器、80 字节数据存储器、16 位定 时器和 8 位/11 位 PWM 定时器、看门狗、电压比较器等…

求将TXT文本转换为Word文档的方法

一&#xff0c;前言 在现代办公环境中&#xff0c;文本文件的转换已成为一项常见的任务。其中&#xff0c;将TXT文本转换为Word文档是最常见的需求之一。这种转换不仅可以帮助我们更好地编辑和格式化文本&#xff0c;还可以提高文件的安全性和兼容性。本文将详细介绍如何将TXT…

iOS开发者必备的实时查看应用程序运行日志技术

目录 一、设备连接 二、使用克魔助手查看日志 三、过滤我们自己App的日志 &#x1f4dd; 摘要&#xff1a; 本文介绍了如何在iOS iPhone设备上实时查看输出在console控制台的日志。通过克魔助手工具&#xff0c;我们可以连接手机并方便地筛选我们自己App的日志。 &#x1f4…

表单全选反选(前端)

1.Html和JavaScript <table><tr><th class"allCheck"><input type"checkbox" name"" id"checkAll"> <span class"all">全选</span></th><th>商品</th><th>商…

gitee 本地文件提交到仓库

一、准备工作 1.下载Git Bash Git Bash官网下载地址 http://www.git-scm.com/download/ 点此跳转 2.注册或登录gitee gitee官网地址 https://gitee.com/ 点此跳转 没有账号选择注册有账号的话直接登陆 3.在gitee中新建一个空的仓库 登陆成功后点进个人主页&#xff0c;点击…