antd desigen tree 4.0增加右击增删改按钮

本文详细介绍了如何在Ant Design的Tree组件中实现右键点击节点时增加添加、删除和修改功能。通过React组件和Ant Design图标库,结合API调用来处理树形数据的增删改操作,并使用Modal组件处理确认对话框。同时,文章还展示了如何处理右键菜单的位置和逻辑判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

antd desigen tree 4.0增加右击增删改按钮

废话不多说,看代码

import React, { Component } from 'react'
import { Tree, Tooltip, Modal, Form, Input, message, Alert } from 'antd';
import { PlusCircleOutlined, EditOutlined, MinusCircleOutlined, SoundTwoTone } from '@ant-design/icons';
import { reqGetTreeNode, reqAddTreeNode, reqUpdateTreeNode, reqDeleteTreeNode } from '@/services/api';
const { DirectoryTree } = Tree;
export default class TreeNode extends Component {
    formRef = React.createRef();
    state = {
        role: 0,
        treeData: [],
        defaultExpandedKeys: '',
        NodeTreeItem: null, //右键菜单
        visible: false,
        isModalVisible: false,//是否显示modal 新建组织或者修改组织
        isHideAdd: '',      //是否展示添加按钮
        isHideUpdate: '',   //是否展示修改按钮
        isHideDelete: '',  //是否展示删除按钮
        operType: '',      //区别Modal弹出框的类型,(添加,修改,删除用的是一个Modal)
        text: '',
        isLoading: true
    }


    getTreeNode = async () => {
        const changeListFiled = (list) => {
            let newList = []
            if (list && list.length > 0) {
                list.forEach(t => {
                    let newItem = {
                        title: t.text,
                        key: t.id,
                        children: t.children
                    }
                    newList.push(newItem)
                    if (t.children && t.children.length > 0) {
                        newItem.children = changeListFiled(t.children)
                    }
                })
            }
            return newList
        }
        const result = await reqGetTreeNode();
        let res = changeListFiled(result.data);
        console.log(res)
        this.addIsLeaf(res)
        this.setState({
            treeData: res,
            defaultExpandedKeys: res[0].key,
            isLoading: false
        })
    }
    addIsLeaf = (treenode) => {
        treenode.forEach((item) => {
            if (item.children.length === 0) {
                item.isLeaf = true
            } else {
                this.addIsLeaf(item.children)
            }
        })
    }
    componentDidMount() {
        this.getTreeNode();
    }

    onSelect = async (keys, info) => {
        this.setState({ NodeTreeItem: null });
        const { key, pos } = info.node;
        //这里写点击tree节点的事件逻辑
    }

    //右键点击事件(注意,这里的右键的Tooltip位置不是很精确,需要微调)
    onRightClick = ({ event, node }) => {
        const pos = node.pos.split('-').length - 1;
        if (pos === 1) {
            this.setState({
                NodeTreeItem: {
                    pageX: -75,
                    pageY: event.pageY - 100,
                    key: node.key,
                    name: node.title,
                    pos: pos
                },
                isHideUpdate: '',
                isHideDelete: 'none',
                isHideAdd: ''
            });
        } else {
            this.setState({
                NodeTreeItem: {
                    pageX: -75,
                    pageY: event.pageY - 135,
                    key: node.key,
                    name: node.title,
                    pos: pos
                },
                isHideAdd: '',
                isHideUpdate: '',
                isHideDelete: ''
            });
        }
    }
    //增删改组件
    getNodeTreeMenu() {
        const { pageX, pageY } = { ...this.state.NodeTreeItem };
        const tmpStyle = {
            position: 'relative',
            maxHeight: 40,
            textAlign: 'center',
            zIndex: '1000',
            left: `${pageX}px`,
            top: `${pageY}px`,
            display: 'flex',
            flexDirection: 'row',
        };
        const menu = (
            <div
                style={tmpStyle}
            >
                <div style={{ alignSelf: 'center', marginLeft: 10, display: this.state.isHideAdd }} onClick={this.handleAddSub}>
                    <Tooltip placement="bottom" title="添加子节点" >
                        <PlusCircleOutlined />
                    </Tooltip>
                </div>
                <div style={{ alignSelf: 'center', marginLeft: 10, display: this.state.isHideUpdate }} onClick={this.handleEditSub}>
                    <Tooltip placement="bottom" title="修改节点">
                        <EditOutlined />
                    </Tooltip>
                </div>
                {this.state.NodeTreeItem.category === 1 ? '' : (
                    <div style={{ alignSelf: 'center', marginLeft: 10, display: this.state.isHideDelete }} onClick={this.handleDeleteSub}>
                        <Tooltip placement="bottom" title="删除该节点">
                            <MinusCircleOutlined />
                        </Tooltip>
                    </div>
                )}
            </div>
        );
        return (this.state.NodeTreeItem == null) ? '' : this.state.role ===
            0 ? menu : '';
    }

    //添加按钮弹出添加Modal
    handleAddSub = () => {
        this.setState({ isModalVisible: true, operType: 'add' })
    }
    //修改按钮弹出修改Modal
    handleEditSub = () => {
        const { NodeTreeItem } = this.state;
        this.setState({ isModalVisible: true, operType: 'update' })
        this.formRef.current.setFieldsValue({ name: NodeTreeItem.name });
    }
    //删除按钮弹出删除Modal
    handleDeleteSub = () => {
        this.setState({ isModalVisible: true, operType: 'delete' })
    }

    //节点添加方法
    toAdd = async (values) => {
        const { NodeTreeItem } = this.state;
        let formData = {
            nodeName: values.name,
            nodeId: NodeTreeItem.key
        }
        console.log(formData)
        const result = await reqAddTreeNode(formData);
        if (result.msg === 'success') {
            message.success('节点添加成功')
        } else {
            message.error('节点添加失败,请重试')
        }
        this.setState({ isModalVisible: false })
        this.getTreeNode();
    }

    //节点更新方法
    toUpdate = async (values) => {
        const { NodeTreeItem } = this.state;
        let formData = {
            nodeName: values.name,
            nodeId: NodeTreeItem.key
        }
        const result = await reqUpdateTreeNode(formData);
        if (result.msg === 'success') {
            message.success('节点修改成功')
        } else {
            message.error('节点修改失败,请重试')
        }
        this.setState({ isModalVisible: false })
        this.getTreeNode();
    }

    //节点删除方法
    toDelete = async () => {
        const { NodeTreeItem } = this.state;
        let formData = {
            nodeId: NodeTreeItem.key
        }
        const result = await reqDeleteTreeNode(formData);
        if (result.msg === 'success') {
            message.success('节点删除成功')
        } else {
            message.error('节点删除失败,请重试')
        }
        this.setState({ isModalVisible: false, NodeTreeItem: null })
        this.getTreeNode();
    }

    //Modal确定的回调
    handleOk = () => {
        const { operType } = this.state;
        this.formRef.current.validateFields().then(values => {
            if (operType === 'add') {
                this.toAdd(values);
            } else if (operType === 'update') {
                this.toUpdate(values);
            } else {
                this.toDelete();
            }
        }).catch(reason => {
            message.warning('表单输入不允许为空,请检查');
        })
    }


    //Modal取消的回调
    handleCancel = (e) => {
        this.formRef.current.resetFields();
        this.setState(() => {
            return ({ isModalVisible: false })
        });
    }


    render() {
        const { isModalVisible, operType, treeData, isLoading, defaultExpandedKeys } = this.state;
        if (isLoading == true) {
            return null
        } else {
            return (
                <>
                    <Alert message="右击菜单树即可增删改" type="success" style={{
                        margin: -12,
                        marginBottom: 24,
                    }} />
                    <div style={{ display: 'flex', marginRight: '20px' }}>
                        <DirectoryTree
                            multiple
                            defaultExpandAll
                            // defaultExpandedKeys={}
                            onSelect={this.onSelect}
                            treeData={treeData}
                            onRightClick={this.onRightClick}
                            style={{ width: '550px' }}
                        />
                        <div style={{ position: 'relative', }}>
                            {this.state.NodeTreeItem != null ? this.getNodeTreeMenu() : ""}
                        </div>
                    </div>


                    <Modal
                        title={operType === 'add' ? '添加节点' : operType === 'delete' ? '删除节点' : '修改节点'}
                        visible={isModalVisible}
                        onOk={this.handleOk}
                        okText="确定"
                        onCancel={this.handleCancel}
                        cancelText="取消"
                        forceRender={true}
                    >
                        {operType === 'add' ? '请输入要添加节点的名称' : operType === 'delete' ? '您确定要删除该节点吗?' : '请输入要修改节点的名称'}
                        <Form
                            name="normal"
                            ref={this.formRef}
                            style={{ display: operType === 'delete' ? 'none' : '' }}
                        >
                            <Form.Item
                                name="name"
                                rules={[
                                    { required: operType === 'delete' ? false : true, message: '节点名称不允许为空' },
                                ]}
                            >
                                <Input placeholder="请输入节点名称" />
                            </Form.Item>
                        </Form>
                    </Modal>
                </>
            )
        }

    }
}

参考于https://blog.youkuaiyun.com/weixin_47809584/article/details/122332719
对存在的问题进行了修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值