Ant Design的可编辑Tree的实现操作


Posted in Javascript onOctober 31, 2020

前言

最近在用Ant Design写一个后台,遇到的需求就是实现一个可动态增减和编辑子节点的Tree。GitHub上看了一圈,没好用和合适的。索性就基于Ant Design中的Tree组件写一个。

实现的效果如下:

可以增加子节点

可以删除子节点

可以编辑子节点信息

可以取消编辑信息

具体的效果图如下:

Ant Design的可编辑Tree的实现操作

主要的就是借助 TreeNode 的 title 属性,它的类型是string|ReactNode。

正文

经过分析,一个节点的数据结构应该是

{
  value: 'Root', // 显示的信息
  defaultValue: 'Root', // 当某一节点进入编辑状态,然后点击close按钮,节点的信息应该恢复原始状态,
  key: '0-1', // 节点的Key,全局唯一
  parentKey: '0', // 父节点的Key
  isEditable: false // 是否处于可编辑状态
  children:[] // 子节点
}

通过数据结构组装TreeNode的代码如下:

data= [
   {
    value: 'Root',
    defaultValue: 'Root',
    key: '0-1',
    parentKey: '0',
    isEditable: false
   }
  ];
  
  state={
    data: this.data
  }
 
renderTreeNodes = data => data.map((item) => {
  if (item.isEditable) { // 编辑状态下
   item.title = (
    <div>
     <input value={item.value}
      onChange={(e) => this.onChange(e, item.key)}/>
     <Icon type='close' style={{marginLeft:10}} onClick={() => this.onClose(item.key, item.defaultValue)}/>
     <Icon type='check' style={{marginLeft:10}} onClick={() => this.onSave(item.key)}/>
    </div>
   );
  } else {
   item.title = (
    <div>
     <span>
      {item.value}
     </span>
     <Icon style={{ marginLeft: 10 }} type='edit' onClick={() => this.onEdit(item.key)} />
     <Icon style={{ marginLeft: 10 }} type='plus' onClick={() => this.onAdd(item.key)} />
     {item.parentKey === '0' ? null : (<Icon style={{ marginLeft: 10 }} type='minus' onClick={() => this.onDelete(item.key)} />)} // 根节点没有删除按钮
    </div>
   )
  }
 
  if (item.children) {
   return (
    <TreeNode title={item.title} key={item.key} dataRef={item}>
     {this.renderTreeNodes(item.children)}
    </TreeNode>
   );
  }
 
  return <TreeNode {...item}/>;
 })
 
 ...
 // 渲染界面
 render() {
  return (
   <div>
    <Tree>
     {this.renderTreeNodes(this.state.data)}
    </Tree>
   </div>
  )
 }

之后所有的增删修改等都是先修改data这个数组中的数据,然后使用this.setState({ data: this.data })更新界面,具体的看下代码就成,很简单。

最后优化这个组件的时候,遇到一个比较坑的。本来想是当在某节点上增加子节点时,父节点自动展开,代码逻辑上没有问题,但是必须手动执行过一次展开或者搜索的操作,所写的逻辑才能生效。

后来没办法,只能在生命周期函数中DOM加载完毕后主动触发下:

componentDidMount() {
  this.onExpand([]); // 手动触发,否则会遇到第一次添加子节点不展开的Bug
 }

代码放在GitHub上了,地址是 react-editable-tree,欢迎有同样需要的小伙伴参考,star和fork 也是极好的。

补充知识:关于antd Select 限制选择个数的解决方案

应用场景描述:

Select 被form 所包裹,且被getFieldDecorator修饰。所以值的改变应该通过form的setFieldsValue方法。

Select模式肯定会是multiple。且以最多三个值举例。

解决思路如下:

1 起初是想在Select的onchange事件中判断values的数量,数量大于三个的时候来重新setFieldsValue;且把最后的选项值替换成刚刚选择的值。

后来发现setFieldsValue方法不起作用,Select的值会一直增加。后来想想可能是 setFieldsValue与onchange 冲突,通过setFieldsValue 无法改变onchange后的值。

2 最后通过重新查看文档。发现还有一个方法可用,即 validator。验证值,通过验证所选值的数量是否大于三个,然后重新setFieldsValue ;发现此法可行。从而解决该疑难杂症。

好,最后附上代码供参考:

changeValues = (rule ,value , callback)=> {
const { setFieldsValue } = this.props.form ;

let newArr ;

if (value.length > 3){


newArr = [].concat(value.slice(0,2), value.slice(-1) ) ;


setFieldsValue({


"languages" : newArr ,


})


callback('最多选择三种语言')

} else {


newArr = value ;


callback()

}
}
 
<FormItem>
{getFieldDecorator('languages', {
rules:[{required: true,message : '请选择三种语言',
validator : changeValues
}],
validateTrigger : 'onChange',
})(
<Select mode='multiple' >
 

<Option key={1} value={1}>1</Option>

<Option key={2} value={2}>2</Option>
 
<Option key={3} value={3}>3</Option>

<Option key={4} value={4}>4</Option>

<Option key={5} value={5}>5</Option>
</Select>
)}
</FormItem>

以上这篇Ant Design的可编辑Tree的实现操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
(function($){...})(jQuery)的意思
Jul 22 Javascript
客户端js判断文件类型和文件大小即限制上传大小
Nov 20 Javascript
jQuery防止click双击多次提交及传递动态函数或多参数
Apr 02 Javascript
jQuery中element选择器用法实例
Dec 29 Javascript
DOM节点的替换或修改函数replaceChild()用法实例
Jan 12 Javascript
深入学习JavaScript的AngularJS框架中指令的使用方法
Mar 05 Javascript
原生js实现网易轮播图效果
Apr 10 Javascript
详解webpack es6 to es5支持配置
May 04 Javascript
React Native第三方平台分享的实例(Android,IOS双平台)
Aug 04 Javascript
详解vue2.0 不同屏幕适配及px与rem转换问题
Feb 23 Javascript
vue用BMap百度地图实现即时搜索功能
Sep 26 Javascript
详解vue3.0 的 Composition API 的一种使用方法
Oct 26 Javascript
antd多选下拉框一行展示的实现方式
Oct 31 #Javascript
解决antd 下拉框 input [defaultValue] 的值的问题
Oct 31 #Javascript
Vue使用CDN引用项目组件,减少项目体积的步骤
Oct 30 #Javascript
vue+swiper实现左右滑动的测试题功能
Oct 30 #Javascript
利用vue3+ts实现管理后台(增删改查)
Oct 30 #Javascript
vue项目页面嵌入代码块vue-prism-editor的实现
Oct 30 #Javascript
解决vue侦听器watch,调用this时出现undefined的问题
Oct 30 #Javascript
You might like
php urlencode()与urldecode()函数字符编码原理详解
2011/12/06 PHP
javascript 动态参数判空操作
2008/12/22 Javascript
jQuery UI 应用不同Theme的办法
2010/09/12 Javascript
jQuery1.6 类型判断实现代码
2011/09/01 Javascript
js处理json以及字符串的比较等常用操作
2013/09/08 Javascript
JQuery记住用户名和密码的具体实现
2014/04/04 Javascript
javascript实现类似超链接的效果
2014/12/26 Javascript
js判断空对象的实例(超简单)
2016/07/26 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
AngularJs Injecting Services Into Controllers详解
2016/09/02 Javascript
JS双击变input框批量修改内容
2016/12/12 Javascript
vue服务端渲染添加缓存的方法
2018/09/18 Javascript
JS无限级导航菜单实现方法
2019/01/05 Javascript
angular多语言配置详解
2019/05/16 Javascript
angular中的post请求处理示例详解
2020/06/30 Javascript
JavaScript实现多层颜色选项卡嵌套
2020/09/21 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
Python设计模式之观察者模式实例
2014/04/26 Python
浅析Python中的join()方法的使用
2015/05/19 Python
Python爬虫实现简单的爬取有道翻译功能示例
2018/07/13 Python
Python基础知识点 初识Python.md
2019/05/14 Python
python async with和async for的使用
2019/06/20 Python
最新版 Windows10上安装Python 3.8.5的步骤详解
2020/11/28 Python
python中类与对象之间的关系详解
2020/12/16 Python
Jupyter Notebook 安装配置与使用详解
2021/01/06 Python
Django项目在pycharm新建的步骤方法
2021/03/02 Python
实习生个人找工作的自我评价
2013/10/30 职场文书
人力资源部经理岗位职责规定
2014/02/23 职场文书
奠基仪式主持词
2014/03/20 职场文书
幼儿园优秀班主任事迹材料
2014/05/14 职场文书
本科毕业生自荐信
2014/05/26 职场文书
素质教育标语
2014/06/27 职场文书
县委务虚会发言材料
2014/10/20 职场文书
2014年培训工作总结范文
2014/11/27 职场文书
怀孕辞职信怎么写
2015/02/28 职场文书
行政介绍信范文
2015/05/04 职场文书