react -> antd (Table 与 Cascader 平级数据转树形实操)
如果你刚开始学习前端或者 React,将 UI 框架作为你的第一步可能不是最好的主意。 (这是引用antd官网的一句话),虽然说一开始用antd作为UI框架对新手来说并不是很好,但是如果工作需要呢,那就不得不这样做了。
下面我就挑两个常用而且对新手稍微有点难度组件来进行讲解,分别是table
表格和 Cascader
级联选择。
antd -> Table 树形数据展示
效果如下:
第一步:打开链接,完成安装和初始化
和引入antd
两个步骤;
第二步:把src里面的文件全部删除,然后分别创建 App.js
、 data.js
、 index.js
index.js 代码如下:
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/lib/button/style';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
data.js 是我封装的数据,代码如下:
export default class Model {
static get(){
const datas=[
{
id:'01',
name:"第一级01",
children:[
{
id:'001',
name:"第二级01",
children:[
{
id:'0001',
name:'第三级01'
},
{
id:'0002',
name:'第三级02'
}
]
},
{
id:'002',
name:'第二级02',
}
]
},
{
id:'02',
name:'第一级02',
},
]
return datas;
}
}
App.js 开始使用Table进行实操啦,代码如下:
import React, { Component } from 'react';
import Model from './data'
import {Table} from 'antd';
import 'antd/dist/antd.css';
const columns = [{
title: '编码',
dataIndex: 'id',
}, {
title: '名称',
dataIndex: 'name',
}
];
export default class App extends Component{
state={
tableData:[], //表格数据
}
componentDidMount () {
// 获取数据树
this.handleDataTree();
}
handleDataTree=()=>{
// 获取data.js里面的数据
const da = Model.get();
if(da && da.length>0){
this.handleGetChild(da);
this.setState({
tableData:da,
})
}
}
handleGetChild = (data) =>{
for(let x = 0,le =data.length; x<le;x +=1){
data[x] = {
...data[x],
key:data[x].id,
code:data[x].id,
name:data[x].name,
}
if (data[x].children && data[x].children.length > 0) {
this.handleGetChild(data[x])
}
}
}
render(){
return(
<div>
<Table
columns={columns}
dataSource={this.state.tableData}
pagination={false} //不展示分页器,如果需要删除该行代码即可
rowKey={recode => recode.id} //表格行的key
/>
</div>
)
}
}
注意: 1.Table里面带的参数可以看官网的API。
2.如果只想展示到某一级的话就只需要在调用this.handleGetChild(da,index);
的时候传递一个数据(就是代码里的index),然后再
if (data[x].children && data[x].children.length > 0) {
this.handleGetChild(data[x],index+1)
}
这段代码里面加上一个index+ 1 最后在写一个if语句判断一下就可以。
细讲 :函数handleDataTree()
在获取到数据后判断,如果数据的长度大于1那么就会先执行handleGetChild()
然后再把数据传递给this.state.tableData
。至于这里为什么要调用函数来处理数据而不是直接处理数据的原因是:
如果数据只有一两层那还好,直接写就是了,但是如果数据有N层了呢,那就很复杂了,所以采用``````handleGetChild() ```把数据传过去然后解析,如果这条数据里面的chilidren还有值的话,就再调用一下这个函数。这样无论数据有多少层就都可以轻松展示了。
antd-Cascader 级联选择(把平级数据改为树形)
除了App.js
和data.js
这两个页面的代码跟上面的不一样,其他的操作都是一样的,我们先来看下效果:
data.js 代码如下:
export default class Model {
static get(){
const datas=[
{id:'01',
name:'第一层01',
parentId:'0'
},
{id:'001',
name:'第二层001',
parentId:'01'
},
{id:'002',
name:'第二层002',
parentId:'01'
},
{id:'0010',
name:'第三层0010',
parentId:'001'
},
{id:'0020',
name:'第三层0020',
parentId:'002'
},
{id:'0021',
name:'第三层0021',
parentId:'002'
},
]
return datas;
}
}
App.js 代码如下:
import React, { Component } from 'react';
import Model from './data'
import {Cascader} from 'antd';
import 'antd/dist/antd.css';
export default class App extends Component{
state={
cascaderData:[], //数据
}
onChange=(value)=> {
console.log(value);
}
componentDidMount () {
// 获取数据树
this.handleDataTree();
}
handleDataTree=()=>{
// 获取data.js里面的数据
const da = Model.get();
if(da && da.length>0){
let dataMap = {};
da.forEach((item)=>{
dataMap[item.id]={key:item.id,value:item.id,label:item.name,parentId:item.parentId}
})
let root={};
for(const key in dataMap){
if(key){
const {parentId} = dataMap[key];
if(parentId === '0'){
root = dataMap[key]
}else if(dataMap[parentId]){
if(!dataMap[parentId].children){
dataMap[parentId].children=[]
}
dataMap[parentId].children.push(dataMap[key])
}
}
}
this.setState({
cascaderData:[root]
})
}
}
render(){
return(
<div>
<Cascader options={this.state.cascaderData} onChange={this.onChange} placeholder="Please select" />
</div>
)
}
}
这里需要注意的是如果想要完成改代码就需要找到子元素的某个数据 = 父元素的某个数据,只有找到这个原理才能完成这个效果。
这里的const {parentId} = dataMap[key];
是把dataMap[key]里的parentId解构出来。