Ant Design的可編輯Tree的實(shí)現(xiàn)操作
前言
最近在用Ant Design寫(xiě)一個(gè)后臺(tái),遇到的需求就是實(shí)現(xiàn)一個(gè)可動(dòng)態(tài)增減和編輯子節(jié)點(diǎn)的Tree。GitHub上看了一圈,沒(méi)好用和合適的。索性就基于Ant Design中的Tree組件寫(xiě)一個(gè)。
實(shí)現(xiàn)的效果如下:
可以增加子節(jié)點(diǎn)
可以刪除子節(jié)點(diǎn)
可以編輯子節(jié)點(diǎn)信息
可以取消編輯信息
具體的效果圖如下:
主要的就是借助 TreeNode 的 title 屬性,它的類型是string|ReactNode。
正文
經(jīng)過(guò)分析,一個(gè)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)應(yīng)該是
{ value: 'Root', // 顯示的信息 defaultValue: 'Root', // 當(dāng)某一節(jié)點(diǎn)進(jìn)入編輯狀態(tài),然后點(diǎn)擊close按鈕,節(jié)點(diǎn)的信息應(yīng)該恢復(fù)原始狀態(tài), key: '0-1', // 節(jié)點(diǎn)的Key,全局唯一 parentKey: '0', // 父節(jié)點(diǎn)的Key isEditable: false // 是否處于可編輯狀態(tài) children:[] // 子節(jié)點(diǎn) }
通過(guò)數(shù)據(jù)結(jié)構(gòu)組裝TreeNode的代碼如下:
data= [ { value: 'Root', defaultValue: 'Root', key: '0-1', parentKey: '0', isEditable: false } ]; state={ data: this.data } renderTreeNodes = data => data.map((item) => { if (item.isEditable) { // 編輯狀態(tài)下 item.title = ( <div> <input value={item.value} onChange={(e) => this.onChange(e, item.key)}/> <Icon type='close' style={{marginLeft:10}} onClick={() => this.onClose(item.key, item.defaultValue)}/> <Icon type='check' style={{marginLeft:10}} onClick={() => this.onSave(item.key)}/> </div> ); } else { item.title = ( <div> <span> {item.value} </span> <Icon style={{ marginLeft: 10 }} type='edit' onClick={() => this.onEdit(item.key)} /> <Icon style={{ marginLeft: 10 }} type='plus' onClick={() => this.onAdd(item.key)} /> {item.parentKey === '0' ? null : (<Icon style={{ marginLeft: 10 }} type='minus' onClick={() => this.onDelete(item.key)} />)} // 根節(jié)點(diǎn)沒(méi)有刪除按鈕 </div> ) } if (item.children) { return ( <TreeNode title={item.title} key={item.key} dataRef={item}> {this.renderTreeNodes(item.children)} </TreeNode> ); } return <TreeNode {...item}/>; }) ... // 渲染界面 render() { return ( <div> <Tree> {this.renderTreeNodes(this.state.data)} </Tree> </div> ) }
之后所有的增刪修改等都是先修改data這個(gè)數(shù)組中的數(shù)據(jù),然后使用this.setState({ data: this.data })更新界面,具體的看下代碼就成,很簡(jiǎn)單。
最后優(yōu)化這個(gè)組件的時(shí)候,遇到一個(gè)比較坑的。本來(lái)想是當(dāng)在某節(jié)點(diǎn)上增加子節(jié)點(diǎn)時(shí),父節(jié)點(diǎn)自動(dòng)展開(kāi),代碼邏輯上沒(méi)有問(wèn)題,但是必須手動(dòng)執(zhí)行過(guò)一次展開(kāi)或者搜索的操作,所寫(xiě)的邏輯才能生效。
后來(lái)沒(méi)辦法,只能在生命周期函數(shù)中DOM加載完畢后主動(dòng)觸發(fā)下:
componentDidMount() { this.onExpand([]); // 手動(dòng)觸發(fā),否則會(huì)遇到第一次添加子節(jié)點(diǎn)不展開(kāi)的Bug }
代碼放在GitHub上了,地址是 react-editable-tree,歡迎有同樣需要的小伙伴參考,star和fork 也是極好的。
補(bǔ)充知識(shí):關(guān)于antd Select 限制選擇個(gè)數(shù)的解決方案
應(yīng)用場(chǎng)景描述:
Select 被form 所包裹,且被getFieldDecorator修飾。所以值的改變應(yīng)該通過(guò)form的setFieldsValue方法。
Select模式肯定會(huì)是multiple。且以最多三個(gè)值舉例。
解決思路如下:
1 起初是想在Select的onchange事件中判斷values的數(shù)量,數(shù)量大于三個(gè)的時(shí)候來(lái)重新setFieldsValue;且把最后的選項(xiàng)值替換成剛剛選擇的值。
后來(lái)發(fā)現(xiàn)setFieldsValue方法不起作用,Select的值會(huì)一直增加。后來(lái)想想可能是 setFieldsValue與onchange 沖突,通過(guò)setFieldsValue 無(wú)法改變onchange后的值。
2 最后通過(guò)重新查看文檔。發(fā)現(xiàn)還有一個(gè)方法可用,即 validator。驗(yàn)證值,通過(guò)驗(yàn)證所選值的數(shù)量是否大于三個(gè),然后重新setFieldsValue ;發(fā)現(xiàn)此法可行。從而解決該疑難雜癥。
好,最后附上代碼供參考:
changeValues = (rule ,value , callback)=> { const { setFieldsValue } = this.props.form ; let newArr ; if (value.length > 3){ newArr = [].concat(value.slice(0,2), value.slice(-1) ) ; setFieldsValue({ "languages" : newArr , }) callback('最多選擇三種語(yǔ)言') } else { newArr = value ; callback() } } <FormItem> {getFieldDecorator('languages', { rules:[{required: true,message : '請(qǐng)選擇三種語(yǔ)言', validator : changeValues }], validateTrigger : 'onChange', })( <Select mode='multiple' > <Option key={1} value={1}>1</Option> <Option key={2} value={2}>2</Option> <Option key={3} value={3}>3</Option> <Option key={4} value={4}>4</Option> <Option key={5} value={5}>5</Option> </Select> )} </FormItem>
以上這篇Ant Design的可編輯Tree的實(shí)現(xiàn)操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue中Table組件行內(nèi)右鍵菜單實(shí)現(xiàn)方法(基于 vue + AntDesign)
這篇文章主要介紹了Vue中Table組件行內(nèi)右鍵菜單實(shí)現(xiàn)方法,該項(xiàng)目是基于 vue + AntDesign的,具體實(shí)例代碼給大家介紹的非常詳細(xì) ,需要的朋友可以參考下2019-11-11vue項(xiàng)目純前端實(shí)現(xiàn)的模板打印功能示例代碼
在Vue項(xiàng)目中,通過(guò)使用vue-print-nb插件,可以實(shí)現(xiàn)頁(yè)面的打印功能,這篇文章主要介紹了vue項(xiàng)目純前端實(shí)現(xiàn)的模板打印功能的相關(guān)資料,需要的朋友可以參考下2024-10-10vue使用pdf-dist實(shí)現(xiàn)pdf預(yù)覽以及水印添加
這篇文章主要為大家詳細(xì)介紹了vue如何使用pdf-dist實(shí)現(xiàn)pdf預(yù)覽以及水印添加的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10Vue?elementUI表單嵌套表格并對(duì)每行進(jìn)行校驗(yàn)詳解
element-ui中有詳細(xì)的各種表格及表格方法,下面這篇文章主要給大家介紹了關(guān)于Vue?elementUI表單嵌套表格并對(duì)每行進(jìn)行校驗(yàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01Vue動(dòng)態(tài)加載圖片在跨域時(shí)無(wú)法顯示的問(wèn)題及解決方法
這篇文章主要介紹了解決VUE動(dòng)態(tài)加載圖片在跨域時(shí)無(wú)法顯示的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03