最近在做新項目,用的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();//阻止冒泡 };