首页 > 其他分享 >vue + Ant Design Vue 表格自定义勾选状态

vue + Ant Design Vue 表格自定义勾选状态

时间:2024-05-06 11:11:38浏览次数:15  
标签:vue name 自定义 age any Ant item key id

 

// 勾选规则 // 1.勾选当前不勾联动选子级 // 2.勾选当前需要联动勾选父级 // 3.勾选当前取消需要联动取消子级和联动取消父级,如果存在平级则不取消父级
<template>
  <a-spin :spinning="state.spining">
    <div>
      <a-modal ref="mModal" id="mModal" class="partiallyUpdatedModals" :maskClosable="false" :visible="props.visible"
        v-if="props.visible" :destroy-on-close="true" title="素材部分更新" @ok="handleOk" width="1200px"
        @cancel="handleCancle">
        <div class="partiallyUpdatedModals_box">
          <a-table :columns="state.columns" :data-source="state.tableData" :pagination="false" row-key="id"
            :row-selection="{
    checkStrictly: true,
    hideSelectAll: true,
    selectedRowKeys: state.selectedRowKeys,
    onSelect: onSelectList,
  }">
            <template #bodyCell="{ text, record, index, column }">
              <template v-if="column.dataIndex == 'name'">
                <span v-if="record.pd == 0" style="color: red">{{
    record.name
  }}</span>
              </template>
              <template v-if="column.dataIndex === 'operation' && record.pd == 0">
                <a style="margin: 0 5px" @click="onEmpty(record)">清空</a>
                <a style="margin: 0 5px; color: #ff7875" @click="onDelete(record)">删除</a>
              </template>
            </template>
          </a-table>
        </div>

        <template #footer>
          <a-button @click="handleOk" type="primary">确定</a-button>
          <a-button @click="handleCancle">返回</a-button>
        </template>
      </a-modal>
    </div>
  </a-spin>
</template>

<script setup lang="ts">
import { createVNode, onMounted, reactive, watch, ref } from "vue";
import { message, Modal } from "ant-design-vue";
import {
  ExclamationCircleOutlined,
} from "@ant-design/icons-vue";
const props = defineProps<{
  visible: boolean;
}>();
const emit = defineEmits(["handleOk", "partiallyUpdated"]);

const state = reactive({
  spining: false,
  columns: [
    {
      title: "素材名称",
      dataIndex: "name",
      key: "name",
      width: "200"
    },
    {
      title: "素材编码",
      dataIndex: "key",
      key: "200px",

    },
    {
      title: "所属分类",
      dataIndex: "age",
      key: "age",
      width: "200px",
    },
    {
      title: "更新素材明细",
      dataIndex: "address",
      key: "address",
    },
    {
      title: "操作",
      dataIndex: "operation",
      width: "200px",
      key: "operation",
    },
  ],
  tableData: [
    {
      id: 1,
      key: 1,
      name: "1",
      pd: 0,
      age: 60,
      address: "1",
      parentId: null,
      children: [
        {
          id: 11,
          key: 11,
          name: "1-1",
          age: 42,
          parentId: 1,
        },
        {
          id: 12,
          key: 12,
          name: "1-2",
          age: 30,
          parentId: 1,
          children: [
            {
              id: 121,
              key: 121,
              name: "1-2-1",
              age: 16,
              parentId: 12,
            },
          ],
        },
        {
          id: 13,
          key: 13,
          name: "1-3",
          age: 72,
          parentId: 1,
          children: [
            {
              id: 131,
              key: 131,
              name: "1-3-1",
              age: 42,
              parentId: 13,
              children: [
                {
                  id: 1311,
                  key: 1311,
                  name: "1-3-1-1",
                  age: 25,
                  parentId: 131,
                },
                {
                  id: 1312,
                  key: 1312,
                  name: "1-3-1-2",
                  age: 18,
                  parentId: 131,
                },
              ],
            },
          ],
        }
      ],
    },
    {
      id: 2,
      key: 2,
      name: "2",
      age: 32,
      address: "2",
      pd: 0,
      parentId: null,
    },
    {
      id: 31,
      key: 31,
      name: "31",
      pd: 0,
      age: 60,
      address: "31",
      parentId: null,
      children: [
        {
          id: 311,
          key: 211,
          name: "31-1",
          age: 42,
          parentId: 31,
        },
        {
          id: 312,
          key: 312,
          name: "31-2",
          age: 30,
          parentId: 1,
          children: [
            {
              id: 3121,
              key: 3121,
              name: "31-2-1",
              age: 16,
              parentId: 312,
            },
          ],
        },
        {
          id: 313,
          key: 313,
          name: "31-3",
          age: 72,
          parentId: 31,
          children: [
            {
              id: 3131,
              key: 3131,
              name: "31-3-1",
              age: 42,
              parentId: 313,
              children: [
                {
                  id: 31311,
                  key: 31311,
                  name: "31-3-1-1",
                  age: 25,
                  parentId: 3131,
                },
                {
                  id: 31312,
                  key: 31312,
                  name: "31-3-1-2",
                  age: 18,
                  parentId: 3131,
                },
              ],
            },
          ],
        }
      ],
    },
  ],
  selectedRowKeys: [] as any,
});
const handleOk = () => { };
const handleCancle = () => {
  emit("partiallyUpdated", false);
};
// 规则 
// 1.勾选当前不勾选子级
// 2.勾选当前需要联动勾选父级
// 3.勾选当前取消需要联动取消子级
// 4 勾选当前需要联动取消父级,如果存在平级则不取消父级
const onSelectList = (record: any, selected: any, selectedRows: any) => {
  console.log('onSelect----record', record);
  console.log('onSelect,----selected', selected);
  console.log('onSelect---selectedRows', selectedRows);
  if (selected) {
    onTableSelectChange(record.id);
  } else {
    onCancellation(record);
  }
}

// 选中
const onTableSelectChange = (id: any) => {
  let arr = JSON.parse(JSON.stringify(state.tableData))
  const result5 = getParentNode(arr, (item: any) => {
    return {
      // 递归结果
      result: item,
      // 递归结束条件
      endTag: item.id === id,
      // 子项的名称
      childName: 'children',
      // 得到的结果是否删除子项
      deleteChildren: true
    };
  });
  if (state.selectedRowKeys.length == 0) {
    state.selectedRowKeys = result5.map((itme: any) => itme.id);
  } else {
    let res = result5.map((itme: any) => itme.id);
    res.forEach((item: any) => {
      // 检查第二个数组中的元素在第一个数组中是否已存在
      let found = state.selectedRowKeys.some((elem: any) => elem == item);
      // // 如果未找到,则将该元素添加到结果数组中
      if (!found) {
        state.selectedRowKeys.push(item);
      }
    });
  }
};
// 取消
const onCancellation = (record: any) => {
  // 勾选当前取消需要联动取消子级
  let chArr1 = getAllChildIds(record);
  let chArr2 = JSON.parse(JSON.stringify(state.selectedRowKeys));
  const chResult = chArr2.filter((item: any) => !chArr1.includes(item));
  state.selectedRowKeys = chResult;

  // 勾选当前需要联动取消父级,如果存在平级则不取消父级
  let arr = JSON.parse(JSON.stringify(state.tableData))
  const result5 = getParentNode(arr, (item: any) => {
    return {
      // 递归结果
      result: item,
      // 递归结束条件
      endTag: item.id === record.id,
      // 子项的名称
      childName: 'children',
      // 得到的结果是否删除子项
      deleteChildren: true
    };
  });
  let array1 = result5.map((itme: any) => itme.id)
  let array2 = state.selectedRowKeys;
  const result = array2.filter((item: any) => !array1.includes(item));
  state.selectedRowKeys = result;
  result.forEach((element: any) => {
    onTableSelectChange(element)
  });

};


// 递归查找子节点id
function getAllChildIds(obj: any) {
  let ids: any = [];
  // 获取当前对象的id
  if (obj.id) {
    ids.push(obj.id);
  }

  // 检查是否有子节点
  if (Array.isArray(obj.children)) {
    // 遍历子节点
    obj.children.forEach((child: any) => {
      // 递归获取子节点的id
      const childIds = getAllChildIds(child);
      // 将子节点的id添加到数组中
      ids = ids.concat(childIds);
    });
  }

  return ids;
}

// 递归查找 当前父级
const getParentNode = (list: any = [], fn = new Function('return {}')) => {
  if (!Array.isArray(list)) throw new Error(`'${list}' not an array.`);
  if (typeof fn !== 'function') throw new Error(`'${fn}' not a function.`);

  for (let i in list) {
    let item = JSON.parse(JSON.stringify(list[i])),
      { result = item.id, endTag = item.id === 10, childName = 'children', deleteChildren = true } = fn(item),
      isDelet = deleteChildren && item[childName] && typeof result === 'object';

    if (endTag) {
      if (isDelet) delete item[childName];

      return [result];
    }

    if (item[childName]) {
      let node: any = getParentNode(item[childName], fn);

      if (node !== undefined) {
        if (isDelet) delete item[childName];

        return node.concat(result);
      }
    }
  }
}


// 删除
const onDelete = (val: any) => {
  Modal.confirm({
    title: "提示",
    icon: createVNode(ExclamationCircleOutlined),
    content: "是否删除?",
    width: 460,
    okText: "确认",
    okType: "danger",
    cancelText: "取消",
    onOk() {
      state.tableData = state.tableData.filter(item => item.key != val.key);
    },
    onCancel() { },
  });

}
// 清空
const onEmpty = (val: any) => {
  Modal.confirm({
    title: "提示",
    icon: createVNode(ExclamationCircleOutlined),
    content: "是否清空勾选状态?",
    width: 460,
    okText: "确认",
    okType: "danger",
    cancelText: "取消",
    onOk() {
      let array1 = getAllChildIds(val);
      let array2 = state.selectedRowKeys;
      const result = array2.filter((item: any) => !array1.includes(item));
      state.selectedRowKeys = result;
    },
    onCancel() { },
  });

}


</script>

<style scoped lang="scss">
.partiallyUpdatedModals_box {
  height: 600px;
  overflow: auto;
}
</style>
<style lang="scss">
.partiallyUpdatedModals .ant-modal-footer {
  text-align: center !important;
}
</style>

 

标签:vue,name,自定义,age,any,Ant,item,key,id
From: https://www.cnblogs.com/zxh-bug/p/18174631

相关文章

  • Vue3 除了 keep-alive,还有哪些页面缓存的实现方案
    引言有这么一个需求:列表页进入详情页后,切换回列表页,需要对列表页进行缓存,如果从首页进入列表页,就要重新加载列表页。对于这个需求,我的第一个想法就是使用keep-alive来缓存列表页,列表和详情页切换时,列表页会被缓存;从首页进入列表页时,就重置列表页数据并重新获取新数据来达到列表......
  • 十分钟,带你了解 Vue3 的新写法
    本文的目的,是为了让已经有Vue2开发经验的 人 ,快速掌握Vue3的写法。因此, 本篇假定你已经掌握Vue的核心内容 ,只为你介绍编写Vue3代码,需要了解的内容。一、Vue3里 script 的三种写法首先,Vue3新增了一个叫做组合式api的东西,英文名叫CompositionAPI。因此Vue3......
  • vue-i18n的9以上的版本中@被用作特殊字符处理,直接用会报错
    vue3项目中使用vue-i18n的9以上的版本实现国际化,使用过程中出现报错:国际化使用 "validation.regExp.name":"仅允许输入字母、数字与_.@字符"报如下错误 Messagecompilationerror:Invalidlinkedformat1|仅允许输入字母、数字与_.@字符Messagecompilationerror:Un......
  • 40.Vue UI组件简单整理
    以下版本:ElementPlus组件库首先基于Vue3的PC端开源UI组件库安装依赖[email protected]中导入并挂载模块importElementPlusfrom'element-plus'import'element-plus/dist/index.css'app.use(ElementPlus)app.mount('#app')注意注意这......
  • TinyVue 3.15.0 正式发布,推出全新的 Charts 图表组件底座,功能更强、图表更丰富!
    你好,我是Kagol。我们非常高兴地宣布,2024年4月8日,TinyVue发布了v3.15.0......
  • vue3早已具备抛弃虚拟DOM的能力了
    前言jquery时代更新视图是直接对DOM进行操作,缺点是频繁操作真实DOM,性能差。react和vue时代引入了虚拟DOM,更新视图是对新旧虚拟DOM树进行一层层的遍历比较,然后找出需要更新的DOM节点进行更新。这样做的缺点就是如果DOM树很复杂,在进行新旧DOM树比较的时候性能就比较差了。那么有没......
  • VMware ESXi 8.0U2b macOS Unlocker HP (惠普) HPE (慧与) OEM 定制版自定义镜像
    VMwareESXi8.0U2bmacOSUnlockerHP(惠普)HPE(慧与)OEM定制版自定义镜像ESXi8.0U2标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)OEM定制版请访问原文链接:VMwareESXi8.0U2bmacOSUn......
  • VMware ESXi 8.0U2b macOS Unlocker Dell (戴尔) OEM 定制版自定义镜像 A06
    VMwareESXi8.0U2bmacOSUnlockerDell(戴尔)OEM定制版自定义镜像A06ESXi8.0U2标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)OEM定制版请访问原文链接:VMwareESXi8.0U2bmacOSUnlocke......
  • VMware ESXi 7.0U3p macOS Unlocker HP (惠普) HPE (慧与) OEM 定制版自定义镜像
    VMwareESXi7.0U3pmacOSUnlockerHP(惠普)HPE(慧与)OEM定制版自定义镜像ESXi7.0U3标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)OEM定制版请访问原文链接:VMwareESXi7.0U3pmacOSUn......
  • VMware ESXi 7.0U3p macOS Unlocker Dell (戴尔) OEM 定制版自定义镜像 A20
    VMwareESXi7.0U3pmacOSUnlockerDell(戴尔)OEM定制版自定义镜像A20ESXi7.0U3标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)OEM定制版请访问原文链接:VMwareESXi7.0U3pmacOSUnlocke......