React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动

这篇具有很好参考价值的文章主要介绍了React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现的效果图如下:
React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动,react,JS,react.js,javascript,前端
如Ant Design Vue 中所示,并没有提供获取半选节点的方法,当设置checked和checkStrictly时,父子节点也不再自动关联了
React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动,react,JS,react.js,javascript,前端

前提:从后端可以获取的数据分别是完整的树型数据、所有选中的节点数据(一个数组、同时包含 父节点和子节点),具体的大概数据可以看下面
树形结构(二重),parId是-1则表示是父节点数据:
React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动,react,JS,react.js,javascript,前端
这是返回的已选中节点的数组:
React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动,react,JS,react.js,javascript,前端
下面是具体的代码:

state = {
  treeData: [], // 树形数据
  checkedKeys: [],
  checkable: false, // 因为我的页面是树型结构在页面右侧,根据左侧显示具体(看自己需求)
  loading: true,
  halfChecked: [], // 半选
  checked: [] // 全选
};

render() {
const { checkedKeys, treeData, checkable, halfChecked, checked, loading } = this.state
<Tree
  ref={r => this.treeRef = r}
  className={styles.menuTree}
  blockNode
  showLine
  // selectable={false}
  checkable={checkable}
  defaultExpandAll
  // checkedKeys={checkedKeys}
  checkedKeys={{
    checked,
    halfChecked
  }}
  checkStrictly
  onCheck={({ checked: ck, halfChecked: hc, ...oth }, { checked, node: { props: { dataRef } } }) => {
    // 选择
    if (checked && dataRef.id) {
      ck = ck.filter(i => i != `${dataRef.id}`).concat(`${dataRef.id}`);
    }
    // 如果有子级,则全部选上
    if(dataRef.parId == '-1'&&dataRef.childList&&dataRef.childList.length > 0){
      const kidKeys = this.getCKidKey(dataRef.childList);
      if(checked){
        ck = ck.concat(kidKeys);
      }else{
          ck = ck.filter(k=>{
          const bo= !kidKeys.includes(k);
          return bo;
        })
      }
    }
    // 如果选中的是子级,其父级也默认选中;取消选中时如果其父级下无选中内容,父级取消选中
    if(dataRef.parId != '-1'){
      if(checked){
        ck.push(dataRef.parId.toString())
        ck = Array.from(new Set(ck));
      }else{
        const ckId = dataRef.id; // 当前选中子级的id
        const ckParId = dataRef.parId; // 当前选中de子级的父级id
        const childList = this.treeMap[ckParId]?.childList; // 当前选中子级的父级 包含的子级
        let isHave = false // 父级下的子级是否有选中的,默认无选中的
        childList.forEach((item => {
          const ass = ck.includes(item.id.toString())
          if(ass) { // 如果还有选中的
            isHave = true
            return
          }
        }))
        if(!isHave){
          ck = ck.filter(item => item != ckParId)
        }
      }
    }
    const lastAllData = Array.from(new Set([...ck, ...hc]))
    this.parentStatus(lastAllData);
  }}
>
  {this.renderTreeNodes(treeData)}
</Tree>
}

主要是onCheck方法里面的处理,下面是用到的一些方法

// 所有已选节点分成两组,全选、半选。
parentStatus = (checked) => { // 这里的checked是指传入所有已选节点
  const { treeData } = this.state; 
  const pData = [] // 半选的父级id数组
  const allPData = [] // 全选的父级id数组
  checked.forEach(i => {
    treeData.forEach(j =>{
      if(i == j.id){ // 如果有选中的父级
        const ckPList = [] // 选中父级的子级数组
        j.childList.forEach(r =>{
          ckPList.push(r.id.toString())
        })
        if(this.isContained(checked, ckPList)){
          allPData.push(j.id.toString())
        }else{
          pData.push(i.toString())
        }
      }
    })
  })
  const halfCkData = [] // 半选状态数据
  const allCkData = [] // 全选状态数据
  for(const i of checked){
    pData.includes(i)&&halfCkData.push(i);
    !pData.includes(i)&&allCkData.push(i);
  }
  this.setState({
    checked: allCkData,
    halfChecked: halfCkData,
  })
}

// 判断一个数组是否包含了另一个数组的全部元素
isContained = (a, b) => {
  // a和b其中一个不是数组,直接返回false
  if (!(a instanceof Array) || !(b instanceof Array)) return false;
  const len = b.length;
  // a的长度小于b的长度,直接返回false
  if (a.length < len) return false;
  for (let i = 0; i < len; i++) {
      if (!a.includes(b[i])) return false;
  }
  return true;
};

// 
ckeys = []

getKidKey = kids => {
  kids.reduce((p, c, ci, arr) => {
    p.push(c.key);
    if (c.children) {
      this.getKidKey(c.children);
    }
    return p;
  }, this.ckeys);
}

getCKidKey = kids => {
  this.getKidKey(kids);
  const cks = [...this.ckeys];
  this.ckeys = []
  return cks;
}

ps因为代码是随着需求优化慢慢增加的,所以命名可能有点乱,方法也是比较杂又多,写出来了就随它了,懒得优化就这样了。如果有帮助到你的话就很nice啦~文章来源地址https://www.toymoban.com/news/detail-648118.html

到了这里,关于React antd tree树组件 - 父子节点没有自动关联情况下 - 显示半选、全选状态以及实现父子节点互动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • react父子组件通信

    父传子:最常见 把父组件中的数据传给子组件 子传父:子组件调用父组件传递过来的参数,并且把想要传递的数据当成函数的实参传入即可 【子组件通过调用父组件传递到子组件的方法向父组件传递数据】 对于子传父中子组件还是先调用了父组件传递过来的参数,之后再向

    2024年02月07日
    浏览(44)
  • React中父子组件参数传递讲解

    结合案例:github搜索案例 案例结果展示如下图 1.父容器代码 说明:父容器中包含了两个组件模块,分别是Search和List,用来搜索和显示 2.搜索Search子模块代码 3.展示Lisi子模块代码 父子参数传递分析 1.子(Search)传父(App) 首先在父容器APP的state中创建状态属性,再传给子模块Sea

    2024年02月09日
    浏览(39)
  • 【react从入门到精通】React父子组件通信方式详解(有示例)

    【分享几个国内免费可用的ChatGPT镜像】 【10几个类ChatGPT国内AI大模型】 【用《文心一言》1分钟写一篇博客简直yyds】 【用讯飞星火大模型1分钟写一个精美的PPT】 在上一篇文章《JSX详解》中我们了解了什么是jsx以及jsx的语法规则。 本文中我们将详细了解React父子组件通信方式

    2024年02月05日
    浏览(105)
  • 【react框架】结合antd做表单组件的一些心得记录

    作为一个前端最常遇见的需求场景就是写表单、写表格。写多了会逐渐的积累一些开发心得,此文章根据我使用vue和react的经验记录了一些东西,抛砖引玉的给大家看看。 举例react项目,在做表单的很多时候,我都是从antd上把其中一个form组件例子复制下来,然后再看看提供了

    2024年02月07日
    浏览(100)
  • React antd upload组件上传视频并实现视频预览

    记录问题:antd的upload组件文档中对于视频的上传预览没有明确的文档demo,在这里记录一下 项目需求:支持图片及视频的上传并实现预览,点击上传后不会立即请求接口上传资源,后续点击确定再上传 上代码

    2024年02月04日
    浏览(49)
  • React + Typescript + Antd:封装通用的字典组件DXSelect

    在开发中,我们经常遇到这样的场景,在表单中,有个下拉框,选择对应的数据。 那么这个下拉框的选项,就是字典。一搬的做法是,通过antd的Select来实现,代码如下:

    2024年02月15日
    浏览(81)
  • 【react + antd】antd如何自定义请求使用antd的upload组件实现图片上传且可预览可删除

    官网给出的案例无法使用封装好的请求方式上传图片,以及 无法满足上传图片后获取接口url、名称等信息的的业务需求 。这个时候需要用到customRequest这个api。 但是很遗憾,官网没有给出具体案例。 不过——博主自己试出来了( ̄︶ ̄) 要使用upload,特别重要的属性就是file

    2024年02月17日
    浏览(54)
  • react Hook+antd封装一个优雅的弹窗组件

    前言 在之前学vue2的时候封装过一个全局的弹窗组件,可以全局任意地方通过this调用,这次大创项目是用react技术栈,看了一下项目需求,突然发现弹窗还是比较多的,主要分为基础的弹窗以及form表单式的弹窗,如果只是无脑的去写代码,那些项目也没啥必要了。正好react和

    2024年02月13日
    浏览(42)
  • react结合antd的Table组件实现动态单元格合并

    首先看一下antd的Table表单组件,合并单元格,用到了rowSpan(合并行)和colSpan(合并列)  后台返回的数据 我们希望把category的值相同的,行合并成一个单元格 类似于这种  rowSpan这个属性可以指定合并行。例如说第一行,指定rowSpan为3,意思就是合并三行,则后面紧挨的两行的ro

    2024年02月12日
    浏览(50)
  • react和vue2/3父子组件的双向绑定

    目录 Vue3 父子传值:props(attrs)/emit 父传子 props 父child :属性名=\\\"变量\\\" 子props=defineProps({属性名:type...}) attrs父作用域(除 class、 style 、 props )属性集合 父child :属性名=\\\"变量\\\",属性名=\\\"常量\\\" 子 attrs = useAttrs() 子传父emits+@=v-on: 父child @事件名\\\"=\\\"parentClick\\\",parentClick(msg) 子emi

    2024年02月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包