最近在做新项目,用的umi框架,使用的Antd的UI组件,之前也了解过Antd的使用,但是实际自己写起来才发现有好多问题
- 从新项目开始到现在,查antd文档最多的就是树形控件Tree,可能是比较复杂吧,并且项目中的需求和之前的不一样,好多地方都需要重新看文档实现。
- 异步加载树节点数据,需要实现tree的loadData方法
- 官方实例中的渲染树节点方法
renderTreeNodes = data => data.map(item => { if (item.children) { return ( <TreeNode title={item.title} key={item.key} dataRef={item}> {this.renderTreeNodes(item.children)} </TreeNode> ); } return <TreeNode key={item.key} {...item} dataRef={item} />; });
- 官方实例中的加载方法
onLoadData = treeNode => new Promise(resolve => { if (treeNode.props.children) {//如果树节点已经有子节点时,返回 resolve(); return; } setTimeout(() => {//模拟请求,结束后设置数据源的children属性 treeNode.props.dataRef.children = [ { title: 'Child Node', key: `${treeNode.props.eventKey}-0` }, { title: 'Child Node', key: `${treeNode.props.eventKey}-1` }, ]; this.setState({ treeData: [...this.state.treeData], }); resolve(); }, 1000); });
- 使用umi框架,加载方法
onLoadData = (treeNode) => { return this.props.dispatch({ type: 'catalogue/getCatalogueChildList', payload: { type: this.props.type, id: treeNode.props.dataRef.id, }, }); }; //model中的网络请求,获取子节点方法 *getCatalogueChildList({ payload }, { select, call, put }) { const res = yield call(getCatalogueChildList, payload); if (res && res.success) { const catalogue = yield select((_) => _.catalogue); let catalogues = catalogue.catalogues; const parentCatalogue = catalogues.filter( (catalogue) => catalogue.id == payload.id, )[0]; if (parentCatalogue) { parentCatalogue.children = res.data.data;//设置子节点为父节点的children属性 yield put({ type: 'updateState', payload: { catalogues: catalogues, }, }); } } else { console.log(res); } },
- 树节点上添加自定义按钮
- 想直接复制之前项目中的代码,但是看了发现写的有点复杂,通过自定义树节点和监听鼠标事件,来控制按钮显示和隐藏,所以就想有没有简单点的方法
- 在网上查了查,发现可以直接通过css中的hover状态来控制
.ant-tree-node-content-wrapper { width: calc(100% - 32px); .ant-tree-title > span span { width: calc(100% - 16px); display: inline-block; } .ant-tree-title > span .anticon { display: none; } } .ant-tree-node-content-wrapper:hover { background-color: rgba(24, 144, 255, 0.1); .ant-tree-title > span .anticon { display: inline-block; } }
- 渲染树节点的方法
renderTreeNodes = (data) => { return ( data && data.map((item) => { if (item.children) { return ( <Tree.TreeNode title={ <span> <span>{item.title}</span> <Icon type='copy' style={{float: 'right', marginTop: 5}} onClick={(e)=>this.copyCatalogueId(e, item)} /> </span> } key={item.id} dataRef={item} isLeaf={item.contentType != 1} > {this.renderTreeNodes(item.children)} </Tree.TreeNode> ); } return ( <Tree.TreeNode key={item.id} title={ <span> <span>{item.title}</span> <Icon type='copy' style={{float: 'right', marginTop: 5}} onClick={(e)=>this.copyCatalogueId(e, item)} /> </span>} dataRef={item} isLeaf={item.contentType != 1} /> ); }) ); };
- 复制文本方法
//创建input元素,把文字设置到input里面,执行execCommand的copy方法复制 copyCatalogueId = (e, item) => { const input = document.createElement('input'); document.body.appendChild(input); input.setAttribute('value', item.contentCode); input.select(); document.execCommand('copy'); message.success('目录编码复制成功!'); document.body.removeChild(input); e.stopPropagation();//阻止冒泡 };