思想
在react的世界裏,都是狀態變更(數據變更)來驅動dom變化,動態添加dom不像以前用jquery一樣append一個<li>
或者一個<td>
這樣了,而是通過裝載<li>
或者<td>
數據數組[]來動態添加dom,下面的例子實現使用了antd的組件庫
參考:https://ant.design/components/form-cn/#components-form-demo-dynamic-form-item
實例
實現
1.引用
import React, { Component, PropTypes } from 'react';
import { Form, Input, Radio, Row, Col, Upload, Icon, Button, message, Select, DatePicker,Modal} from 'antd';
2.初始化
constructor(props) {
super(props);
this.state = {
hover: [],
};
}
3.內容組件
內容組件其實是一個<ul><li>
,遍歷了一個<li>
的數組articleContent,CSS樣式見最後
render(){
const liClass = this.state.hover[index] ? "rectanglesON " : "rectanglesOFF ";
const formItems = this.state.articleData.articleContent.map((k, index) => {
return (
<li key={index} ref={"li_" + index} datatype={k.contentType} className={liClass} onMouseEnter={this.handleMouseEnter.bind(this,index)} onMouseLeave{this.handleMouseLeave.bind(this,index)}
onClick={this.handleClickByModule.bind(this,index,k.contentType)}>
//業務需要顯示的東西
<div>li標籤裏要顯示的東西</div>
//懸停時右下角的按鈕
<div className={this.state.hover[index]?'actionShow':'actionHide'}>
<div className={(index > 0)?'domShow':'domHide'}>
<Button type="primary" size="small" className="mr-5" onClick={this.handleClickBySortUp.bind(this,index)}><Icon type="caret-up" />上移</Button>
</div>
<div className={(index < this.state.articleData.articleContent.length - 1)?'domShow':'domHide'}>
<Button type="primary" size="small" className="mr-5" onClick={this.handleClickBySortDown.bind(this,index)}><Icon type="caret-down" />下移</Button>
</div>
<div>
<Button type="primary" size="small" className="mr-5" onClick={this.handleClickByDelete.bind(this,index)}><Icon type="delete" />刪除</Button>
</div>
</div>
</li>
)
});
//ul
return (
<FormItem label="內容">
<ul className='listContent'>
{formItems}
</ul>
</FormItem>
)
}
4.事件
//鼠標移到內容模塊上時觸發的事件
handleMouseEnter(key) {
let arg = this.state.hover;
arg[key] = true;
this.setState({
hover: arg
});
}
//鼠標離開內容模塊時觸發的事件
handleMouseLeave(key) {
let arg = this.state.hover;
arg[key] = false;
this.setState({
hover: arg
});
}
//點擊向上排序按鈕事件
handleClickBySortUp(index, e) {
e.stopPropagation();
let arr = this.state.articleData.articleContent;
if (index != 0) {
let temp = arr[index - 1];
arr[index - 1] = arr[index];
arr[index] = temp;
this.setState({
articleData: this.state.articleData,
});
}
}
//點擊向下排序按鈕事件
handleClickBySortDown(index, e) {
e.stopPropagation();
let arr = this.state.articleData.articleContent;
if (index != arr.length) {
let temp = arr[index + 1];
arr[index + 1] = arr[index];
arr[index] = temp;
this.setState({
articleData: this.state.articleData,
});
}
}
//點擊刪除按鈕事件
handleClickByDelete(index, e) {
e.stopPropagation();
let arr = this.state.articleData.articleContent;
arr.splice(index, 1);
this.setState({
articleData: this.state.articleData,
});
}
5.CSS樣式
.rectanglesON {
word-wrap: break-word;
min-height: 200px;
border: 1px dashed #808080;
list-style-type: none;
margin-bottom: 10px;
cursor: pointer;
}
.rectanglesOFF {
word-wrap: break-word;
min-height: 200px;
border: 1px dashed #d3d3d3;
list-style-type: none;
margin-bottom: 10px;
}
.listContent li {
position: relative;
.actionShow {
position: absolute;
bottom: 0;
right: 0;
padding-left: 10px;
display: flex;
}
.actionHide {
position: absolute;
bottom: 0;
right: 0;
padding-left: 10px;
display: none;
}
}
.mr-5{
margin-right:5px;
}