文章目录
实现功能
编写用户管理模块前端界面,实现用户的增加、查询、删除、更新操作,为了体现React模块的复用性,拆分为1个父组件和2个子组件,整体效果如下:
整体页面:
新增和编辑用户弹出窗UserMaintainForm
组件关系
组件名 | 类别 | 功能 |
---|---|---|
AccountManage | 父组件 | 用户管理页面 |
AccountRoleSearchBar | 子组件1 | 包含2个<Input> 和2个<Button> 的搜索栏 |
导UserMaintainForm | 子组件2 | 点击管理页面新增和编辑按钮,弹出的Modal |
基本思路
父组件通过传递一个回调函数获取子组件的值,关键代码如下:
父组件中关键代码
// fields就是子组件表单的值,具体表现为两个input的输入
// searchUser是获取子组件数据后父组件中的处理方法
searchUser = fields => {
// todo something
}
render(){
// 搜索栏方法
const searchBarMethods = {
handleSearch: this.searchUser,
handleAdd: this.setModalVisible,
};
……
// 搜索栏子组件
<AccountRoleSearchBar
inputArray={this.inputArray}
buttonArray={this.buttonArray}
{...searchBarMethods}
/>
}
子组件中关键代码
render(){
const {
form: { getFieldDecorator, validateFields, resetFields },
inputArray,
buttonArray,
handleSearch, // 父组件传递进来的方法
handleAdd, // 父组件传递进来的方法
} = this.props;
const leftButtonClick = () => {
validateFields((err, fieldsValue) => {
if (err) return;
resetFields();
handleSearch(fieldsValue); // 子组件传递表单值给父组件
});
};
<Button
type="primary"
icon={buttonArray[0].icon}
htmlType="submit"
onClick={leftButtonClick} //注意看这里
>
{buttonArray[0].text}
</Button>
<Button
style={{ marginLeft: 8 }}
icon={buttonArray[1].icon}
type="primary"
onClick={handleAdd} //注意看这里
>
{buttonArray[1].text}
</Button>
}
完整代码
父组件AccountManage.js
import React, { PureComponent, Fragment } from 'react';
import { Card, Table, Divider, Form, Popconfirm } from 'antd';
import UserMaintainForm from '@/pages/_Manage/UserMaintainForm';
import AccountRoleSearchBar from '@/components/_common/AccountRoleSearchBar';
import { getAllAccounts } from '@/services/account';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
/**
* 用户管理页面,实现用户新增、编辑和删除功能
* @author BecomeBamboo
* @date 2020-02-06
*/
@Form.create()
class AccountManage extends PureComponent {
state = {
selectedUser: {}, // 当前编辑用户信息
userMaintainModalVisible: false, // 用户维护Modal是否显示
};
columns = [
{
title: '用户ID',
dataIndex: 'userName',
key: 'userName',
},
{
title: '用户名',
dataIndex: 'realName',
key: 'realName',
},
{
title: '角色',
dataIndex: 'userRole',
key: 'userRole',
},
{
title: '区域',
dataIndex: 'userArea',
key: 'userArea',
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
render: (text, record) => (
<Fragment>
<a onClick={() => this.handleUpdateUser(true, record)}>编辑</a>
{record.userName !== 'admin' ? <Divider type="vertical" /> : null}
{record.userName !== 'admin' ? (
<Popconfirm
title={`确认删除${record.userName}用户?`}
onConfirm={() => this.handleDelete(record.key)}
>
<a>删除</a>
</Popconfirm>
) : null}
</Fragment>
),
},
];
inputArray = [
{
name: 'userName',
placeHolder: '用户ID',
},
{
name: 'realName',
placeHolder: '用户名',
},
];
buttonArray = [
{
icon: 'search',
text: '查询用户',
},
{
icon: 'plus',
text: '新增用户',
},
];
componentDidMount() {
getAllAccounts().then(res => {
this.setState({
dataArray: res.data,
});
});
}
/**
* 判断用户维护Modal是否显示
*/
setModalVisible = flag => {
this.setState({
userMaintainModalVisible: !!flag,
selectedUser: {},
});
};
/**
* 新增用户
*/
addNewUser = fields => {
// const { dispatch } = this.props;
// dispatch({
// type: 'rule/add',
// payload: {
// desc: fields.desc,
// },
// });
//
// message.success('添加成功');
console.log(fields);
this.setModalVisible(false);
};
/**
* 更新用户
*/
handleUpdateUser = (flag, record) => {
this.setState({
userMaintainModalVisible: !!flag,
selectedUser: record,
});
};
/**
* 删除用户
*/
handleDelete = key => {
const { dataArray } = this.state;
// todo 执行后端删除方法,重新获取用户列表
this.setState({ dataArray: dataArray.filter(item => item.key !== key) });
};
/**
* 根据用户ID和用户名搜索
*/
searchUser = fields => {
getAllAccounts().then(res => {
// 2个input输入为空显示全部用户
if (typeof fields.userName === 'undefined' && typeof fields.realName === 'undefined') {
this.setState({
dataArray: res.data,
});
}
// 2个input输入不正确显示全部用户
else if (
res.data.filter(item => item.userName === fields.userName).length === 0 &&
res.data.filter(item => item.realName === fields.realName).length === 0
) {
this.setState({
dataArray: res.data,
});
}
// 显示搜索用户
else {
this.setState({
dataArray: res.data.filter(
item => item.userName === fields.userName || item.realName === fields.realName
),
});
}
});
};
render() {
const { dataArray, userMaintainModalVisible, selectedUser } = this.state;
// 用户维护页面方法
const modalMethods = {
handleSave: this.addNewUser,
handleCancel: this.setModalVisible,
};
// 搜索栏方法
const searchBarMethods = {
handleSearch: this.searchUser,
handleAdd: this.setModalVisible,
};
return (
<PageHeaderWrapper>
<Fragment title={false}>
<Card bordered={false}>
<AccountRoleSearchBar
inputArray={this.inputArray}
buttonArray={this.buttonArray}
{...searchBarMethods}
/>
<Table dataSource={dataArray} columns={this.columns} />
</Card>
<UserMaintainForm
destroyOnClose
title="用户维护"
record={selectedUser}
visible={userMaintainModalVisible}
{...modalMethods}
/>
</Fragment>
</PageHeaderWrapper>
);
}
}
export default AccountManage;
子组件AccountRoleSearchBar.js
import React, { PureComponent, Fragment } from 'react';
import { Button, Col, Form, Input, Row } from 'antd';
import PropTypes from 'prop-types';
import styles from './index.less';
const FormItem = Form.Item;
/**
* 用户信息和角色信息搜索栏组件
* @author BecomeBamboo
* @date 2020-02-06
*/
@Form.create()
class AccountRoleSearchBar extends PureComponent {
static propTypes = {
inputArray: PropTypes.array,
buttonArray: PropTypes.array,
};
static defaultProps = {
inputArray: [
{
name: 'userName',
placeHolder: '用户ID',
},
{
name: 'realName',
placeHolder: '用户名',
},
],
buttonArray: [
{
icon: 'search',
text: '查询用户',
},
{
icon: 'plus',
text: '新增用户',
},
],
};
/**
* 查询用户和新增用户表单的渲染
*/
renderForm() {
const {
form: { getFieldDecorator, validateFields, resetFields },
inputArray,
buttonArray,
handleSearch,
handleAdd,
} = this.props;
/**
* 左边按钮查询用户
*/
const leftButtonClick = () => {
validateFields((err, fieldsValue) => {
if (err) return;
resetFields();
handleSearch(fieldsValue);
});
};
return (
<Form layout="inline">
<Row gutter={16}>
<Col span={4}>
<FormItem>
{getFieldDecorator(inputArray[0].name)(
<Input placeholder={inputArray[0].placeHolder} />
)}
</FormItem>
</Col>
<Col span={4}>
<FormItem>
{getFieldDecorator(inputArray[1].name)(
<Input placeholder={inputArray[1].placeHolder} />
)}
</FormItem>
</Col>
<Col span={6}>
<span className={styles.submitButtons}>
<Button
type="primary"
icon={buttonArray[0].icon}
htmlType="submit"
onClick={leftButtonClick}
>
{buttonArray[0].text}
</Button>
<Button
style={{ marginLeft: 8 }}
icon={buttonArray[1].icon}
type="primary"
onClick={handleAdd}
>
{buttonArray[1].text}
</Button>
</span>
</Col>
</Row>
</Form>
);
}
render() {
return (
<Fragment>
<div className={styles.tableList}>
<div className={styles.tableListForm}>{this.renderForm()}</div>
</div>
</Fragment>
);
}
}
export default AccountRoleSearchBar;
子组件UserMainForm.js
import React, { PureComponent } from 'react';
import { Form, Input, Select, Modal } from 'antd';
import { getAllRoles } from '@/services/account';
const { Option } = Select;
const FormItem = Form.Item;
/**
* 用户维护Modal组件
* @author BecomeBamboo
* @date 2020-02-06
*/
@Form.create()
class UserMaintainForm extends PureComponent {
state = {
roles: [],
};
elements = [
{
name: 'userName',
desc: '用户ID:',
hint: '请输入英文',
message: '请输入用户ID',
type: 'input',
},
{
name: 'realName',
desc: '用户名:',
hint: '请输入中文',
message: '请输入用户名',
type: 'input',
},
{
name: 'userArea',
desc: '区域:',
hint: '请输入数字:',
message: '请指定监控区域',
type: 'input',
},
{
name: 'password',
desc: '密码:',
hint: '',
message: '请输入密码',
type: 'input',
},
{
name: 'repeatPassword',
desc: '重复密码:',
hint: '',
message: '请重复密码',
type: 'input',
},
{
name: 'userRole',
desc: '角色:',
hint: '请选择角色',
message: '请选择角色',
type: 'select',
},
];
componentDidMount() {
getAllRoles().then(res => {
this.setState({
roles: res.data,
});
});
}
/**
* 点击编辑按钮显示原始表单值
*/
setInitialValue = (ele, record) => {
let value;
switch (ele.name) {
case 'userName':
value = record.userName;
break;
case 'realName':
value = record.realName;
break;
case 'userArea':
value = record.userArea;
break;
default:
value = '';
break;
}
return value;
};
/**
* 渲染UserMaintainForm组件
*/
renderContent = () => {
const {
form: { getFieldDecorator },
record,
} = this.props;
const { roles } = this.state;
return (
<Form layout="vertical">
{this.elements.map(ele => {
if (ele.type === 'select') {
return (
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label={ele.desc}>
{getFieldDecorator(ele.name, {
initialValue: Object.keys(record).length === 0 ? undefined : record.userRole,
rules: [{ required: true, message: ele.message }],
})(
<Select
placeholder={ele.hint}
loading={roles.length === 0}
// onChange={this.handleSelectChange}
>
{roles.map(s => (
<Option key={s.id} value={s.id}>
{s.roleDesc}
</Option>
))}
</Select>
)}
</FormItem>
);
}
return (
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label={ele.desc}>
{getFieldDecorator(ele.name, {
initialValue:
Object.keys(record).length === 0 ? null : this.setInitialValue(ele, record),
rules: [{ required: true, message: ele.message }],
})(<Input placeholder={ele.hint} />)}
</FormItem>
);
})}
</Form>
);
};
render() {
const { destroyOnClose, title, visible, form, handleSave, handleCancel } = this.props;
/**
* UserMaintainModal界面点击确认按钮后触发,清空表单,返回表单数据给父组件
*/
const okHandle = () => {
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
handleSave(fieldsValue);
});
};
return (
<Modal
destroyOnClose={destroyOnClose}
title={title}
visible={visible}
okText="保存"
cancelText="返回"
onOk={okHandle}
onCancel={() => handleCancel()}
>
{this.renderContent()}
</Modal>
);
}
}
export default UserMaintainForm;