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 相关文章推荐
IE和Mozilla的兼容性汇总event
Aug 12 Javascript
js CSS操作方法集合
Oct 31 Javascript
innerHTML 和 getElementsByName 在IE下面的bug 的解决
Apr 09 Javascript
JS中toFixed()方法引起的问题如何解决
Nov 20 Javascript
使用jQuery实现的掷色子游戏动画效果
Mar 14 Javascript
javascript作用域问题实例分析
Jul 13 Javascript
jQuery实现Meizu魅族官方网站的导航菜单效果
Sep 14 Javascript
jQuery实现返回顶部功能
Feb 23 Javascript
Javascript 闭包详解及实例代码
Nov 30 Javascript
JavaScript实现写入文件到本地的方法【基于FileSaver.js插件】
Mar 15 Javascript
layui问题之模拟select点击事件的实例讲解
Aug 15 Javascript
详解JS浏览器事件循环机制
Mar 27 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中file_exists与is_file,is_dir的区别介绍
2012/09/12 PHP
php有道翻译api调用方法实例
2014/12/22 PHP
编写PHP脚本来实现WordPress中评论分页的功能
2015/12/10 PHP
PHP实现单条sql执行多个数据的insert语句方法
2019/10/11 PHP
javascript 常用关键字列表集合
2007/12/04 Javascript
使用jquery实现select添加实现后台权限添加的效果
2011/05/28 Javascript
高效率JavaScript编写技巧整理
2013/08/23 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
2016/04/13 Javascript
深入解析JavaScript中的立即执行函数
2016/05/21 Javascript
浅谈JS运算符&amp;&amp;和|| 及其优先级
2016/08/10 Javascript
利用imgareaselect辅助后台实现图片上传裁剪
2017/03/02 Javascript
Node.js中.pfx后缀文件的处理方法
2017/03/10 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
2017/03/10 Javascript
jQuery 循环遍历改变a标签的href(实例讲解)
2017/07/12 jQuery
JS库中的Particles.js在vue上的运用案例分析
2017/09/13 Javascript
Vue使用枚举类型实现HTML下拉框步骤详解
2018/02/05 Javascript
vue--点击当前增加class,其他删除class的方法
2018/09/15 Javascript
在JS循环中使用async/await的方法
2018/10/12 Javascript
微信小程序实现图片翻转效果的实例代码
2019/09/20 Javascript
JS async 函数的含义和用法实例总结
2020/04/08 Javascript
微信小程序使用GoEasy实现websocket实时通讯
2020/05/19 Javascript
Vuex的各个模块封装的实现
2020/06/05 Javascript
详解JS函数防抖
2020/06/05 Javascript
Python多进程并发(multiprocessing)用法实例详解
2015/06/02 Python
Python实现屏幕截图的代码及函数详解
2016/10/01 Python
开源Web应用框架Django图文教程
2017/03/09 Python
通过python+selenium3实现浏览器刷简书文章阅读量
2017/12/26 Python
Python request设置HTTPS代理代码解析
2018/02/12 Python
Pytorch: 自定义网络层实例
2020/01/07 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
Html5 Canvas动画基础碰撞检测的实现
2018/12/06 HTML / CSS
天游软件面试
2013/11/23 面试题
年终晚会活动方案
2014/08/21 职场文书
《全神贯注》教学反思
2016/02/22 职场文书
MySQL令人咋舌的隐式转换
2021/04/05 MySQL