import React, { useEffect, useState } from 'react';
import { Tree } from 'antd';

import './index.less';

const { TreeNode } = Tree;
import { getSubAreaData } from "@services/area";
import { HeaderWithBack } from "@/components";
import { Button, SearchBar } from "antd-mobile-v5";

const SelectAreaTree = (props: any) => {
const [selectArea, setSelectArea] = useState([]);
const [treeData, setTreeData] = useState([]);
const [selectAreaKeys, setSelectAreaKeys] = useState([]);

useEffect(() => {
getSubAreaData({ areaId: 0 }).then(response => {
const data = response.data;
const initTreeData = [];
for (const dataKey in data) {
initTreeData.push({
title: data[dataKey].areaName,
key: data[dataKey].areaId,
})
}
setTreeData(initTreeData);
});
}, []);

const onLoadData = treeNode => new Promise((resolve) => {
if (treeNode.props.children) {
resolve();
return;
}
getSubAreaData({ areaId: treeNode.props.dataRef.key }).then(response => {
const data = response.data;
const subOrgArray = [];
data.forEach(item => {
subOrgArray.push({ title: item.areaName, key: item.areaId });
});
treeNode.props.dataRef.children = subOrgArray;
setTreeData([...treeData]);
resolve();
});
})

const renderTreeNodes = data => data.map((item) => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode {...item} dataRef={item} />;
})

/**
* 节点选择触发事件
* @param selectKey
* @param e
*/
const treeNodeSelect = (selectKey: any, e: any) => {
if (!selectKey || selectKey.length <= 0) {
return;
}
let checkedNodes = e.checkedNodes;
let selectAreaTemp = [];
for (const checkedNodesKey in checkedNodes) {
selectAreaTemp.push(checkedNodes[checkedNodesKey].props.dataRef)
}

setSelectArea(selectAreaTemp);

let selectAreaKeysTemp = [];
for (const key in selectAreaTemp) {
selectAreaKeysTemp.push(selectAreaTemp[key].key);
}
setSelectAreaKeys(selectAreaKeysTemp);
// selectKey[0] + '', e.selectedNodes[0].props.dataRef.title
}

/**
* 移除选择了的区域
* @param item
*/
const removeAreaItem = (item: any) => {
let selectAreaTemp = [];
let selectAreaKeysTemp = [];
for (const key in selectArea) {
if (selectArea[key].key != item.key) {
selectAreaTemp.push(selectArea[key]);
selectAreaKeysTemp.push(selectArea[key].key);
}
}
setSelectArea(selectAreaTemp);
setSelectAreaKeys(selectAreaKeysTemp);
}

/**
* 移除选择了的区域
* @param item
*/
const removeAllAreaItem = () => {
setSelectArea([]);
setSelectAreaKeys([]);
}

/**
* 确认返回
*/
const bakAndOK = () => {
props.onShowOrClose(selectArea);
}
return (
<div>
<HeaderWithBack title="地图展示区域筛选" onLeftClick={() => {
props.onShowOrClose()
}} />
<div className="content-info">
<div className="content-info-title">
<SearchBar placeholder='输入关键词进行搜索' style={{ '--background': '#ffffff' }} />
</div>
<div className="content-info-select-area">
{
selectArea.map((item) => {
return <div className="content-info-select-area-item">{item.title}<span onClick={() => {
removeAreaItem(item)
}
}>x</span></div>
})
}
</div>
<div className="content-info-tree">
<Tree
checkable
selectable={false}
loadData={onLoadData}
onCheck={treeNodeSelect}
checkedKeys={selectAreaKeys}
checkStrictly={true}
>
{renderTreeNodes(treeData)}
</Tree>
</div>
</div>
<div className="content-info-btn">
<Button block shape='rounded' className="content-info-btn-cancel" onClick={() => {
removeAllAreaItem()
}}>
重置
</Button>
<Button block shape='rounded' className="content-info-btn-ok" onClick={() => {
bakAndOK()
}}>
确认
</Button>
</div>
</div>
);
};

export default SelectAreaTree;

  

.content-info{
padding: 0.15rem;
background-color: #EDF1F7;
max-height:88vh;
overflow-y: scroll;
}
.content-info-title{
padding: 0.1rem 0;
}

.content-info-select-area{
display: flex;
flex-wrap:wrap;
color: #2D3545;
}

.content-info-select-area-item{
background: #FFFFFF;
border-radius: 4px;
padding: 0.02rem 0.1rem;
margin: 0.05rem 0.1rem 0.05rem 0;
}

.content-info-select-area-item span{
margin: 0 0 0 0.2rem;
font-size: 0.15rem;
}

.content-info-tree{
padding: 0.1rem;
border-radius: 6px;
margin-top: 0.1rem;
background-color: #FFF;
}

.content-info-btn{
display: flex;
justify-content:space-between;
margin: 0.1rem 0 0 0;
}

.content-info-btn-cancel{
width: 30%;
margin: 0 0.1rem;
}

.content-info-btn-ok{
width: 70%;
margin: 0 0.1rem;
color: #FFF;
background-image: linear-gradient(107deg, #94A3A8 0%, #383838 94%);
}

//重写tree多选框位置

.ant-tree li span.ant-tree-checkbox {
float: right;
}

:root .ant-tree li span.ant-tree-switcher.ant-tree-switcher_close .ant-tree-switcher-icon, :root .ant-tree li span.ant-tree-switcher.ant-tree-switcher_close .ant-select-switcher-icon {
font-size: 26px;
color: #BFBFBF;
}
:root .ant-tree li span.ant-tree-switcher.ant-tree-switcher_open .ant-tree-switcher-icon, :root .ant-tree li span.ant-tree-switcher.ant-tree-switcher_open .ant-select-switcher-icon {
font-size: 26px;
color: #BFBFBF;
}

.ant-tree-checkbox-wrapper:hover .ant-tree-checkbox-inner, .ant-tree-checkbox:hover .ant-tree-checkbox-inner, .ant-tree-checkbox-input:focus + .ant-tree-checkbox-inner {
border-color: #e7bf97;
}
.ant-tree-checkbox-checked .ant-tree-checkbox-inner {
background-color: #e7bf97;
border-color: #e7bf97;
}

.ant-tree-checkbox-indeterminate .ant-tree-checkbox-inner::after {
background-color: #e7bf97;
}

  

antd动态tree 自定义样式的更多相关文章

  1. vue 动态添加 <style> 样式 vue动态添加 绑定自定义字体样式

    created(){ //动态添加自定义字体样式 let style = document.createElement('style'); style.type = "text/css&qu ...

  2. WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...

  3. checkbox、radio设置自定义样式

    老生常谈,做一个简单的记录.浏览器自带的checkbox和radio样式可能不符合项目要求,通常要做一些自定义样式设置,目前基本的解决思路都是将input[type=checkbox/radio]隐藏 ...

  4. 【转】WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: DataGrid自定义样式: ListView自定义样式: 二.Dat ...

  5. WPF 4 DataGrid 控件(自定义样式篇)

    原文:WPF 4 DataGrid 控件(自定义样式篇)      在<WPF 4 DataGrid 控件(基本功能篇)>中我们已经学习了DataGrid 的基本功能及使用方法.本篇将继续 ...

  6. 关于devexpress报表XtraReport,动态修改报表样式(.repx格式),动态添加数据并使用的理解

    一.基本概念: XtraReports 中的每个报表都由 XtraRepot 类的一个实例表示,或者由该类的子类来表示(这种情况更常见). 因此,每个报表都作为带区的容器使用,而每个带区中都包含报表控 ...

  7. 一步步开发自己的博客 .NET版 剧终篇(6、响应式布局 和 自定义样式)

    前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做 ...

  8. Ueditor上传图片后自定义样式类名

    Ueditor是百度的一个富文本插件,如果使用者会前端语言的话,那适用性就很好,特别是现在移动端纵横的情况.但往往使用者并不懂编程,要让他们使用前端语言的话是不可能的,这就需要我们在开发时就定义好整个 ...

  9. Android RatingBar 自定义样式

    Android RatingBar 自定义样式 1.先定义Style: <style name="RadingStyle" parent="@android:sty ...

  10. WPF CheckBox 自定义样式

    WPF 自定义样式.CheckBox <Style x:Key="EmptyCheckBox" TargetType="CheckBox"> < ...

随机推荐

  1. jmeter取样器之KafkaProducerSampler(往kafka插入数据)

    项目背景 性能测试场景中有一个业务场景的数据抽取策略是直接使用kafka队列,该场景需要准备的测试数据是kafka队列里的数据,故需要实现插入数据到kafka队列,且需要实现控制每分钟插入多少条数据. ...

  2. VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory.

    macOS VirtualBox Bridged Adapter 不能用 I'm running macOS High Sierra 10.13.1 and VirtualBox 5.2.2. Thi ...

  3. 【小记】如果 golang 内存不够了怎么办

    在看 redis 1.0 源码时,总会看到需要申请内存的地方,如果申请不到需要大的内存就会返回 NULL,然后在调用层抛出 oom. 比如 listDup 中在复制特殊 value 或者加入新节点时都 ...

  4. 升级TLS1.3

    初衷:简简单单在网站上挂个单点登录,先在本地跑起来,然后再放到服务器上.然而问题来了: 请求被中止: 未能创建 SSL/TLS 安全通道 简简单单的百度一下,只需要加上这行就可以了~Easy Serv ...

  5. git 指令:丢弃本地所有未提交的更改

    git clean -df //丢弃所有 untracked 的文件 git reset --hard //将 tracked 的文件重置到前一个版本

  6. spring-boot 引入redis

    1.引入redis <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...

  7. SPI接口(续二)

    接下来看SPI接收器数据寄存器RXDAT,下表是它的全部位结构,其地址分别为0x40058014(SPI0).0x4005C014(SPI1). (1)第0到15位(RXDAT)为接收器数据,它包含接 ...

  8. centos-7实现批量ping

    批量ping 脚本 新接手了一个项目,10多个网段,500多机器,看自己机器可以连上多少服务器,一个个ping不符合我们的作风,因此百度了下大神的脚本,按自己的风格修改了,于是有了如下的脚本. 脚本如 ...

  9. Python3之并发(四)---线程锁

    一.线程锁 保证多线程数据的一致性,对锁内的资源进行锁定,同一时间只能有一个线程来修改共享的数据多个线程同时加了同一个锁对象时,先获取到锁的线程会继续运行,未获取到锁的线程会处于堵塞状态,直到前面的线 ...

  10. mongodb添加删除节点及仲裁节点

    温馨提示:此mongodb版本为5.0.11 ,并注意,如果要删除节点,可以直接删除,添加节点前要先删除仲裁节点. rs.remove("192.168.0.180:27017") ...