zent-tree

1.1.0 • Public • Published

Tree 树

树形控件,展示文件结构、组织架构、地理信息等分层数据的控件。

使用指南

  • 支持两种数据格式,递归树形结构和单层列表结构。
  • 组件展示对应传入的data属性,内部不会改变data,具体请看自定义操作的例子。

代码演示

:::demo 基础用法

import { Tree } from 'zent';

const treeData = [{
	id: 1,
	title: '杭州有赞科技有限公司',
	children: [{
		id: 2,
		title: '技术',
		children: [{
			id: 3,
			title: '后端'
		}, {
			id: 4,
			title: '运维'
		}, {
			id: 5,
			title: '前端'
		}]
	}, {
		id: 6,
		title: '产品'
	}]
}];

ReactDOM.render(
	<Tree data={treeData} />
	, mountNode
);

:::

:::demo 列表格式数据源

import { Tree } from 'zent';

const treeData = [{
	id: 1,
	title: '杭州有赞科技有限公司',
}, {
	id: 2,
	title: '技术',
	parentId: 1
}, {
	id: 3,
	title: '后端',
	parentId: 2
}, {
	id: 4,
	title: '运维',
	parentId: 2
}, {
	id: 5,
	title: '前端',
	parentId: 2
}, {
	id: 6,
	title: '产品',
	parentId: 1
}];

ReactDOM.render(
	<Tree dataType="plain" data={treeData} />
	, mountNode
)

:::

:::demo 三种大小

import { Tree } from 'zent';

const treeData = [{
	id: 1,
	title: '杭州有赞科技有限公司',
	children: [{
		id: 2,
		title: '技术',
		children: [{
			id: 3,
			title: '后端'
		}, {
			id: 4,
			title: '运维'
		}, {
			id: 5,
			title: '前端'
		}]
	}, {
		id: 6,
		title: '产品'
	}]
}];

ReactDOM.render(
	<div>
		<Tree data={treeData} size="small" />
		<Tree data={treeData} />
		<Tree data={treeData} size="large" />
	</div>
	, mountNode
);

:::

:::demo 自定义节点展示

import { Tree } from 'zent';

const treeData = [{
	id: 1,
	title: '杭州有赞科技有限公司',
	content: '移动零售服务商',
	children: [{
		id: 2,
		title: '技术',
		content: '职位介绍http://job.youzan.com',
		children: [{
			id: 3,
			title: '后端'
		}, {
			id: 4,
			title: '运维'
		}, {
			id: 5,
			title: '前端'
		}]
	}, {
		id: 6,
		title: '产品',
		content: <a href="http://job.youzan.com">请将简历发送至 joinus@youzan.com</a>,
	}]
}];

const customRender = (data) => (
	<span style={{ fontSize: 16, margin: 0, lineHeight: 1 }}>
		{data.title}
		{data.content ? <small style={{ display: 'block', fontSize: 10 }}>{data.content}</small> : ''}
	</span>
);

ReactDOM.render(
	<Tree data={treeData} render={customRender} />
	, mountNode
)

:::

:::demo 自定义操作

import { Tree, Icon, Radio } from 'zent';

const RadioGroup = Radio.Group;
const originData = [{
	id: 1,
	title: '杭州有赞科技有限公司',
}, {
	id: 2,
	title: '技术',
	parentId: 1
}, {
	id: 3,
	title: '后端',
	parentId: 2
}, {
	id: 4,
	title: '运维',
	parentId: 2
}, {
	id: 5,
	title: '前端',
	parentId: 2
}, {
	id: 6,
	title: '产品',
	parentId: 1
}];

const deepClone = (node, parentId = 0, nodeArray = []) => {
	const copyNode = {
		id: String(Math.random()).replace('0.', ''),
		parentId,
		title: node.title
	};
	nodeArray.push(copyNode);
	
	for (let i = 0, l = node.children && node.children.length || 0; i < l; i++) {
		deepClone(node.children[i], copyNode.id, nodeArray);
	}
	return nodeArray;
}

class TreeExample extends React.Component {
	state = {
		treeData: originData,
		copyType: 'shallow' 
	}

	onDelete = (data) => {
		this.setState({
			treeData: this.state.treeData.filter(item => item.id !== data.id)
		});
	};

	onClone = (data) => {
		const { copyType } = this.state;
	
		if (copyType === 'shallow') {
			const node = Object.assign({}, data, { id: Date.now() });
			this.setState({
				treeData: [...this.state.treeData, node]
			});
		} else if (copyType === 'deep') {
			const nodeArray = deepClone(data, data.parentId);
			this.setState({
				treeData: [...this.state.treeData, ...nodeArray]
			});
		}
	};

	onCopyTypeChange = (e) => this.setState({ copyType: e.target.value });

	render() {
		const { copyType, treeData } = this.state;
		const operations = [{
			name: 'Delete',
			icon: <Icon type="close" />,
			action: this.onDelete
		}, {
			name: 'Clone',
			icon: <Icon type="plus" />,
			action: this.onClone
		}];
	
		return (
			<div>
				<RadioGroup onChange={this.onCopyTypeChange} value={copyType}>
					<Radio value="shallow">浅拷贝</Radio>
					<Radio value="deep">深拷贝</Radio>
				</RadioGroup>
				<hr/>
				<Tree data={treeData} dataType="plain" operations={operations} />
			</div>
		);
	}
}

ReactDOM.render(
	<TreeExample />
	, mountNode
)

:::

:::demo 可选树

import { Tree } from 'zent';

const treeData = [{
	id: 1,
	title: '杭州有赞科技有限公司',
	children: [{
		id: 2,
		title: '技术',
		children: [{
			id: 3,
			title: '后端'
		}, {
			id: 4,
			title: '运维'
		}, {
			id: 5,
			title: '前端'
		}]
	}, {
		id: 6,
		title: '产品'
	}]
}];
const defaultCheckedKeys = [2, 3];
const disabledCheckedKeys = [4, 5];

const onCheck = data => console.log(data);

ReactDOM.render(
	<Tree
		checkable
		data={treeData}
		onCheck={onCheck}
		defaultCheckedKeys={defaultCheckedKeys}
		disabledCheckedKeys={disabledCheckedKeys}
	/>
	, mountNode
)

:::

:::demo 异步加载

import { Tree } from 'zent';

const fetchData = (data, callback) => {
	if (data.level < 4) {
		setTimeout(() => {
			const resData = [];
			const base = Number(data.title.split('-')[0]);
			const step = Math.pow(10, 3 - data.level);
			const level = data.level + 1;
			for (let i = 0, id = '', isLeaf = false; i <= 9; i++) {
				if (level === 4) {
					id = String(base + i);
					isLeaf = true;
				} else {
					id = `${base + step * i}-${base + step * (i + 1)}`;
					isLeaf = false;
				}
				resData.push({ id, level, title: id, isLeaf });
			}
			callback(resData);
		}, 200);
	} else {
		setTimeout(() => callback([]), 200);
	}
}

class TreeExample extends React.Component {
	state = {
		treeData: []
	}

	componentDidMount() {
		const rootData = {
			id: '1-0-10000',
			title: '0-10000',
			level: 0,
			expand: true
		};
		fetchData(rootData, (resData) => {
			const newData = resData.map(item => ({
				...item,
				parentId: rootData.id
			}));
			this.setState({
				treeData: [rootData, ...newData]
			});
		});
	}

	loadMore = (data) => new Promise((resolve, reject) => {
		fetchData(data, (resData) => {
			const newData = resData.map(item => ({
				...item,
				parentId: data.id
			}));
			this.setState({ treeData: [...this.state.treeData, ...newData] });
			resolve();
		});
	});

	render() {
		const { treeData } = this.state;
		return <Tree dataType="plain" data={treeData} loadMore={this.loadMore} />;
	}
}

ReactDOM.render(
	<TreeExample />
	, mountNode
)

:::

API

Tree

参数 说明 类型 默认值 备选值
dataType 数据类型, 默认为tree类型 string 'tree' 'plain'
data 必填, 实际传入的数据, 根据dataType进行识别 array
render 自定义树条目渲染方法, 传入参数为该节点数据 (包含子树) func(data)
operations 自定义操作, 包含 name, icon, action, shouldRender 属性 array[object]
foldable 是否支持点击条目时展开与收起动作 bool true
checkable 是否支持checkbox选择 bool true
onCheck 点击checkbox的回调函数, 传入包含所有点击节点id数组 func(data)
defaultCheckedKeys 默认选中节点id数组 array
disabledCheckedKeys 默认禁选节点id数组 array
size 大小 string 'medium' 'small', 'large'
commonStyle 设置整个tree的外层style object
expandAll 是否展开所有节点 bool false
onExpand 展开节点之后的回调函数 func(data, config)
autoExpandOnSelect 点击节点是否展开 bool true
onSelect 选择树的一个节点的回调函数 func(data, target)
isRoot plain数据类型,判断节点是否为根节点的api func(node)

data

可在每个节点任意添加初下列属性之外的key-value,回调函数中会拿到用户传入的完整数据。

参数 说明 类型 默认值 备选值
id 必填, 数据的唯一标识 number/string
title 必填, 显示内容 string
children 子树 (dataType="tree" 时生效) array[object]
parentId 父节点Id (dataType="plain" 时生效), 根节点为0或不定义 number/string
expand 是否展开 bool false
isLeaf 是否叶子节点 bool false

operations

参数 说明 类型 默认值 备选值
name 必填,显示内容 string
icon 显示icon的className, 或ReactNode string/ReactNode
action 必填,点击回调函数,参数为子树信息 func(data)
shouldRender 是否更新,返回true/false func(data) true

Readme

Keywords

none

Package Sidebar

Install

npm i zent-tree

Weekly Downloads

2

Version

1.1.0

License

MIT

Last publish

Collaborators

  • delai
  • youzan-lc