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. 《基于CNN和SVM的人脸识别系统的设计与实现》论文笔记十六

    一.基本信息 标题:基于CNN和SVM的人脸识别系统的设计与实现 时间:2021 来源:计算机与数字工程 关键词: 人脸识别;卷积神经网络;支持向量机;深度学习; 二.研究内容 问题定义: 针对人脸识 ...

  2. 第14章 Windows管理规范

    第14章 Windows管理规范 我们一直期望但是又害怕写这一章.Windows管理规范(Windows Management Instrumentation,WMI)可能是微软提供给管理员使用最优秀 ...

  3. Unity中的深度测试相关知识与问题

    https://www.jianshu.com/p/f420b55edd0b?utm_campaign=hugo

  4. List集合转换成数组

    我现在有个需求:将File集合转换成MultipartFile数组结构 然后我就开始在网上开启了List转换到数组之旅. 首先来看一个例子 ArrayList<String> list=n ...

  5. Centos 7.5 MySql的安装和配置

    一.安装 三个步骤: wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpmyum -y ins ...

  6. YYYY-MM-dd

    Calendar calendar = Calendar.getInstance();  calendar.set(2019, Calendar.DECEMBER, 31); Date strDate ...

  7. vue 打开页面触发事件

    vue中created(),mounted()与activated()区别及应用 created():在创建vue对象时,当html渲染之前就触发:但是注意,全局vue.js不强制刷新或者重启时只创建 ...

  8. Android中操作 SDCard文件

    1 import android.content.Context; 2 import android.graphics.Bitmap; 3 import android.graphics.Bitmap ...

  9. Operator包的应用

    # -*-coding:utf-8-*- import operator print(operator.add(1,1))    #  加 print(operator.sub(2,1))    #减 ...

  10. Jmeter 5.0 遇见connection reset问题

    问题:大并发时遇见java.net.SocketException: Connection reset 测试过程中经常遇见connection reset ,原因是大数据量发送时,服务器不能接纳那么多 ...