Ant Design的可編輯Tree的實現(xiàn)操作
前言
最近在用Ant Design寫一個后臺,遇到的需求就是實現(xiàn)一個可動態(tài)增減和編輯子節(jié)點(diǎn)的Tree。GitHub上看了一圈,沒好用和合適的。索性就基于Ant Design中的Tree組件寫一個。
實現(xiàn)的效果如下:
可以增加子節(jié)點(diǎn)
可以刪除子節(jié)點(diǎn)
可以編輯子節(jié)點(diǎn)信息
可以取消編輯信息
具體的效果圖如下:

主要的就是借助 TreeNode 的 title 屬性,它的類型是string|ReactNode。
正文
經(jīng)過分析,一個節(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)
}
通過數(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)沒有刪除按鈕
</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這個數(shù)組中的數(shù)據(jù),然后使用this.setState({ data: this.data })更新界面,具體的看下代碼就成,很簡單。
最后優(yōu)化這個組件的時候,遇到一個比較坑的。本來想是當(dāng)在某節(jié)點(diǎn)上增加子節(jié)點(diǎn)時,父節(jié)點(diǎn)自動展開,代碼邏輯上沒有問題,但是必須手動執(zhí)行過一次展開或者搜索的操作,所寫的邏輯才能生效。
后來沒辦法,只能在生命周期函數(shù)中DOM加載完畢后主動觸發(fā)下:
componentDidMount() {
this.onExpand([]); // 手動觸發(fā),否則會遇到第一次添加子節(jié)點(diǎn)不展開的Bug
}
代碼放在GitHub上了,地址是 react-editable-tree,歡迎有同樣需要的小伙伴參考,star和fork 也是極好的。
補(bǔ)充知識:關(guān)于antd Select 限制選擇個數(shù)的解決方案
應(yīng)用場景描述:
Select 被form 所包裹,且被getFieldDecorator修飾。所以值的改變應(yīng)該通過form的setFieldsValue方法。
Select模式肯定會是multiple。且以最多三個值舉例。
解決思路如下:
1 起初是想在Select的onchange事件中判斷values的數(shù)量,數(shù)量大于三個的時候來重新setFieldsValue;且把最后的選項值替換成剛剛選擇的值。
后來發(fā)現(xiàn)setFieldsValue方法不起作用,Select的值會一直增加。后來想想可能是 setFieldsValue與onchange 沖突,通過setFieldsValue 無法改變onchange后的值。
2 最后通過重新查看文檔。發(fā)現(xiàn)還有一個方法可用,即 validator。驗證值,通過驗證所選值的數(shù)量是否大于三個,然后重新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('最多選擇三種語言')
} else {
newArr = value ;
callback()
}
}
<FormItem>
{getFieldDecorator('languages', {
rules:[{required: true,message : '請選擇三種語言',
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的實現(xiàn)操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-router重寫push方法,解決相同路徑跳轉(zhuǎn)報錯問題
這篇文章主要介紹了vue-router重寫push方法,解決相同路徑跳轉(zhuǎn)報錯問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
vue proxy 的優(yōu)勢與使用場景實現(xiàn)
這篇文章主要介紹了vue proxy 的優(yōu)勢與使用場景實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
解決Antd中Form表單的onChange事件中執(zhí)行setFieldsValue不生效
這篇文章主要介紹了解決Antd中Form表單的onChange事件中執(zhí)行setFieldsValue不生效問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

