react组件封装

react组件封装

Posted by SkioFox on January 10, 2019

基于antd的form的封装

通过props传递数据和方法,将数据在父子之间传递,子组件中通过对数据的获取和类型判断动态生成formItem项,实现form的封装

  import React from 'react'
  import { Input, Select, Form, Button, Checkbox, Radio, DatePicker} from 'antd'
  import Utils from '../../utils/utils';
  const FormItem = Form.Item;
  const Option = Select.Option;

  class FilterForm extends React.Component{

      handleFilterSubmit = ()=>{
          // 获取表单的值
          let fieldsValue = this.props.form.getFieldsValue();
          // 将值传递回父级
          this.props.filterSubmit(fieldsValue);
      }
      // 重置
      reset = ()=>{
          this.props.form.resetFields();
      }

      initFormList = ()=>{
          // 获取antD的表单方法
          const { getFieldDecorator } = this.props.form;
          // 获取传递进来的formList
          const formList = this.props.formList;
          const formItemList = [];
          if (formList && formList.length>0){
              // 遍历表单数据
              formList.forEach((item,i)=>{
                  let label = item.label;
                  let field = item.field;
                  let initialValue = item.initialValue || '';
                  let placeholder = item.placeholder;
                  let width = item.width;
                  // 依据type类型获取formItem组件项
                  if (item.type == '时间查询'){
                      const begin_time = <FormItem label="订单时间" key={field}>
                          {
                              getFieldDecorator('begin_time')(
                                  <DatePicker showTime={true} placeholder={placeholder} format="YYYY-MM-DD HH:mm:ss"/>
                              )
                          }
                      </FormItem>;
                      formItemList.push(begin_time)
                      const end_time = <FormItem label="~" colon={false} key={field}>
                          {
                              getFieldDecorator('end_time')(
                                  <DatePicker showTime={true} placeholder={placeholder} format="YYYY-MM-DD HH:mm:ss" />
                              )
                          }
                      </FormItem>;
                      formItemList.push(end_time)
                  }else if(item.type == 'INPUT'){
                      const INPUT = <FormItem label={label} key={field}>
                          {
                              getFieldDecorator([field],{
                                  initialValue: initialValue
                              })(
                                  <Input type="text" placeholder={placeholder} />
                              )
                          }
                      </FormItem>;
                      formItemList.push(INPUT)
                  } else if (item.type == 'SELECT') {
                      const SELECT = <FormItem label={label} key={field}>
                          {
                              getFieldDecorator([field], {
                                  initialValue: initialValue
                              })(
                                  <Select
                                      style=
                                      placeholder={placeholder}
                                  >
                                      {/* getOptionList()依据data动态获取option */}
                                      {Utils.getOptionList(item.list)}
                                  </Select>
                              )
                          }
                      </FormItem>;
                      formItemList.push(SELECT)
                  } else if (item.type == 'CHECKBOX') {
                      const CHECKBOX = <FormItem label={label} key={field}>
                          {
                              getFieldDecorator([field], {
                                  valuePropName: 'checked',
                                  initialValue: initialValue //true | false
                              })(
                                  <Checkbox>
                                      {label}
                                  </Checkbox>
                              )
                          }
                      </FormItem>;
                      formItemList.push(CHECKBOX)
                  }
              })
          }
          return formItemList;
      }
      render(){
          return (
              <Form layout="inline">
                  { this.initFormList() }
                  <FormItem>
                      <Button type="primary" style= onClick={this.handleFilterSubmit}>查询</Button>
                      <Button onClick={this.reset}>重置</Button>
                  </FormItem>
              </Form>
          );
      }
  }
  // getFieldDecorator()内部实现了表单数据的双向绑定
  export default Form.create({})(FilterForm);

请求与全局状态以及拦截器的封装

通过对请求的二次封装,返回promise对象进行异步处理,从而实现统一的请求和错误提示。通过请求状态控制全局loading的显示。这里仅对jsonp和get请求举例

  import JsonP from 'jsonp'
  import axios from 'axios'
  import { Modal } from 'antd'
  export default class Axios {
      // 跨域请求
      static jsonp(options) {
          return new Promise((resolve, reject) => {
              JsonP(options.url, {
                  param: 'callback'
              }, function (err, response) {
                  // console.log(response)
                  if (response.status == 'success') {
                      resolve(response);
                  } else {
                      reject(response.messsage);
                  }
              })
          })
      }

      static ajax(options){   
          let loading;
          // 全局的loading状态,在请求未成功时会触发
          if (options.data && options.data.isShowLoading !== false){
              loading = document.getElementById('ajaxLoading');
              loading.style.display = 'block';
          }
          let baseApi = 'https://www.easy-mock.com/mock/5a7278e28d0c633b9c4adbd7/api';
          return new Promise((resolve,reject)=>{
              axios({
                  url:options.url,
                  method:'get',
                  baseURL:baseApi,
                  timeout:5000,
                  params: (options.data && options.data.params) || ''
              }).then((response)=>{
                  if (options.data && options.data.isShowLoading !== false) {
                      loading = document.getElementById('ajaxLoading');
                      loading.style.display = 'none';
                  }
                  if (response.status == '200'){
                      let res = response.data;
                      if (res.code == '0'){
                          resolve(res);
                      }else{
                          // 错误提示
                          Modal.info({
                              title:"提示",
                              content:res.msg
                          })
                      }
                  }else{
                      reject(response.data);
                  }
              })
          })  
      }
  }     

基于react的权限控制

通过RBAC角色权限模型进行权限设计 核心:角色创建和权限状态管理、角色权限分配、用户权限授权

    import React from 'react'
    import {Card, Button, Form, Input, Select, Tree, Transfer, Modal} from 'antd'
    import axios from '../../axios/index'
    import ETable from '../../components/ETable/index'
    import menuConfig from '../../config/menuConfig'
    import Utils from '../../utils/utils'
    const FormItem = Form.Item;
    const Option = Select.Option;
    const TreeNode = Tree.TreeNode;
    export default class Order extends React.Component{

        state={}

        componentWillMount(){
            this.requestList();   
        }

        requestList = ()=>{
            axios.ajax({
                url:'/role/list',
                data:{
                    params:{}
                }
            }).then((res)=>{
                if(res.code == 0){
                    let list  = res.result.item_list.map((item,i)=>{
                        item.key = i;
                        return item;
                    })
                    this.setState({
                        list
                    })
                }
            })
        }

        // 角色创建
        handleRole = ()=>{
            this.setState({
                isRoleVisible:true
            })
        }

        // 角色提交
        handleRoleSubmit = ()=>{
            let data = this.roleForm.props.form.getFieldsValue();
            axios.ajax({
                url:'role/create',
                data:{
                    params:{
                        ...data
                    }
                }
            }).then((res)=>{
                if(res){
                    this.setState({
                        isRoleVisible:false
                    })
                    this.requestList();
                }
            })
        }

        handlePermission = ()=>{
            if (!this.state.selectedItem) {
                Modal.info({
                    title: '信息',
                    content: '请选择一个角色'
                })
                return;
            }
            this.setState({
                isPermVisible: true,
                detailInfo: this.state.selectedItem
            });
            let menuList = this.state.selectedItem.menus;
            this.setState({
                menuInfo:menuList
            })
        }

        handlePermEditSubmit = ()=>{
            let data = this.roleForm.props.form.getFieldsValue();
            data.role_id = this.state.selectedItem.id;
            data.menus = this.state.menuInfo;
            axios.ajax({
                url:'/permission/edit',
                data:{
                    params:{
                        ...data
                    }
                }
            }).then((res)=>{
                if(res){
                    this.setState({
                        isPermVisible:false
                    })
                    this.requestList();
                }
            })
        }

        // 用户授权
        handleUserAuth = ()=>{
            if (!this.state.selectedItem) {
                Modal.info({
                    title: '信息',
                    content: '未选中任何项目'
                })
                return;
            }
            this.getRoleUserList(this.state.selectedItem.id);
            this.setState({
                isUserVisible: true,
                isAuthClosed: false,
                detailInfo: this.state.selectedItem
            });
        }
        getRoleUserList = (id)=>{
            axios.ajax({
                url:'/role/user_list',
                data:{
                    params:{
                        id:id
                    }
                }
            }).then((res)=>{
                if(res){
                    this.getAuthUserList(res.result);
                }
            })
        }
        // 筛选目标用户
        getAuthUserList = (dataSource) => {
            const mockData = [];
            const targetKeys = [];
            if (dataSource && dataSource.length > 0) {
                for (let i = 0; i < dataSource.length; i++) {
                    const data = {
                        key: dataSource[i].user_id,
                        title: dataSource[i].user_name,
                        status: dataSource[i].status,
                    };
                    if (data.status == 1) {
                        targetKeys.push(data.key);
                    }
                    mockData.push(data);
                }
            }
            this.setState({mockData, targetKeys});
        };
        
        patchUserInfo = (targetKeys) => {
            this.setState({
                targetKeys: targetKeys
            });
        };

        // 用户授权提交
        handleUserSubmit = ()=>{
            let data = {};
            data.user_ids = this.state.targetKeys || [];
            data.role_id = this.state.selectedItem.id;
            axios.ajax({
                url:'/role/user_role_edit',
                data:{
                    params:{
                        ...data
                    }
                }
            }).then((res)=>{
                if(res){
                    this.setState({
                        isUserVisible:false
                    })
                    this.requestList();
                }
            })
        }
        render(){
            const columns = [
                {
                    title: '角色ID',
                    dataIndex: 'id'
                }, {
                    title: '角色名称',
                    dataIndex: 'role_name'
                },{
                    title: '创建时间',
                    dataIndex: 'create_time',
                    render: Utils.formatTime
                }, {
                    title: '使用状态',
                    dataIndex: 'status',
                    render(status){
                        if (status == 1) {
                            return "启用"
                        } else {
                            return "停用"
                        }
                    }
                }, {
                    title: '授权时间',
                    dataIndex: 'authorize_time',
                    render: Utils.formatTime
                }, {
                    title: '授权人',
                    dataIndex: 'authorize_user_name',
                }
            ];
            return (
                <div>
                    <Card>
                        <Button type="primary" onClick={this.handleRole}>创建角色</Button>
                        <Button type="primary" onClick={this.handlePermission}>设置权限</Button>
                        <Button type="primary" onClick={this.handleUserAuth}>用户授权</Button>
                    </Card>           
                    <div className="content-wrap">
                        <ETable
                            updateSelectedItem={Utils.updateSelectedItem.bind(this)}
                            selectedRowKeys={this.state.selectedRowKeys}
                            dataSource={this.state.list}
                            columns={columns}
                        />
                    </div>
                    <Modal
                        title="创建角色"
                        visible={this.state.isRoleVisible}
                        onOk={this.handleRoleSubmit}
                        onCancel={()=>{
                            // this.roleForm.props.qform.resetFields();
                            this.setState({
                                isRoleVisible:false
                            })
                        }}
                    >
                        <RoleForm wrappedComponentRef={(inst) => this.roleForm = inst }/>
                    </Modal>
                    <Modal
                        title="权限设置"
                        visible={this.state.isPermVisible}
                        width={600}
                        onOk={this.handlePermEditSubmit}
                        onCancel={()=>{
                            this.setState({
                                isPermVisible:false
                            })
                        }}>
                            <PermEditForm
                                wrappedComponentRef={(inst) => this.roleForm = inst }
                                detailInfo={this.state.detailInfo}
                                menuInfo={this.state.menuInfo||[]}
                                patchMenuInfo={(checkedKeys)=>{
                                    this.setState({
                                        menuInfo: checkedKeys
                                    });
                                }}
                            />
                    </Modal>
                    <Modal
                        title="用户授权"
                        visible={this.state.isUserVisible}
                        width={800}
                        onOk={this.handleUserSubmit}
                        onCancel={()=>{
                            this.setState({
                                isUserVisible:false
                            })
                        }}>
                            <RoleAuthForm
                                wrappedComponentRef={(inst) => this.userAuthForm = inst }
                                isClosed={this.state.isAuthClosed}
                                detailInfo={this.state.detailInfo}
                                targetKeys={this.state.targetKeys}
                                mockData={this.state.mockData}
                                patchUserInfo={this.patchUserInfo}
                            />
                    </Modal>
                </div>
            );
        }
    }

    // 角色创建表单
    class RoleForm extends React.Component{

        render(){
            const { getFieldDecorator } = this.props.form;
            const formItemLayout = {
                labelCol: {span: 5},
                wrapperCol: {span: 16}
            };
            return (
                <Form layout="horizontal">
                    <FormItem label="角色名称" {...formItemLayout}>
                        {
                            getFieldDecorator('role_name',{
                                initialValue:''
                            })(
                                <Input type="text" placeholder="请输入角色名称"/>
                            )
                        }
                    </FormItem>
                    <FormItem label="状态" {...formItemLayout}>
                        {
                            getFieldDecorator('state',{
                                initialValue:1
                            })(
                            <Select>
                                <Option value={1}>开启</Option>
                                <Option value={0}>关闭</Option>
                            </Select>
                        )}
                    </FormItem>
                </Form>
            );
        }
    }
    RoleForm = Form.create({})(RoleForm);

    // 设置权限表单
    class PermEditForm extends React.Component {
        state = {};
        // 设置选中的节点,通过父组件方法再传递回来
        onCheck = (checkedKeys) => {
            this.props.patchMenuInfo(checkedKeys);
        };
        renderTreeNodes = (data,key='') => {
            return data.map((item) => {
                let parentKey = key+item.key;
                if (item.children) {
                    return (
                        // tree结构
                        <TreeNode title={item.title} key={parentKey} dataRef={item} className="op-role-tree">
                        {/*递归tree*/}
                            {this.renderTreeNodes(item.children,parentKey)}
                        </TreeNode>
                    );
                } else if (item.btnList) {
                    return (
                        <TreeNode title={item.title} key={parentKey} dataRef={item} className="op-role-tree">
                            { this.renderBtnTreedNode(item,parentKey) }
                        </TreeNode>
                    );
                }
                return <TreeNode {...item} />;
            });
        };

        renderBtnTreedNode = (menu,parentKey='')=> {
            const btnTreeNode = []
            menu.btnList.forEach((item)=> {
                console.log(parentKey+'-btn-'+item.key);
                btnTreeNode.push(<TreeNode title={item.title} key={parentKey+'-btn-'+item.key} className="op-role-tree"/>);
            })
            return btnTreeNode;
        }

        render() {
            const { getFieldDecorator } = this.props.form;
            const formItemLayout = {
                labelCol: {span: 5},
                wrapperCol: {span: 18}
            };
            const detail_info = this.props.detailInfo;
            const menuInfo = this.props.menuInfo;
            return (
                <Form layout="horizontal">
                    <FormItem label="角色名称:" {...formItemLayout}>
                        <Input disabled maxLength="8" placeholder={detail_info.role_name}/>
                    </FormItem>
                    <FormItem label="状态:" {...formItemLayout}>
                        {getFieldDecorator('status',{
                            initialValue: '1'
                        })(
                            <Select style=
                                    placeholder="启用"
                            >
                                <Option value="1">启用</Option>
                                <Option value="0">停用</Option>
                            </Select>
                        )}
                    </FormItem>
                    <Tree
                        checkable
                        defaultExpandAll
                        onCheck={(checkedKeys)=>this.onCheck(checkedKeys)}
                        checkedKeys={menuInfo ||[]}
                    >
                        <TreeNode title="平台权限" key="platform_all">
                            {this.renderTreeNodes(menuConfig)}
                        </TreeNode>
                    </Tree>
                </Form>
            )
        }
    }

    PermEditForm = Form.create({})(PermEditForm);

    // 用户授权表单
    class RoleAuthForm extends React.Component {

        filterOption = (inputValue, option) => {
            return option.title.indexOf(inputValue) > -1;
        };
        handleChange = (targetKeys) => {
            this.props.patchUserInfo(targetKeys);
        };

        render() {
            const formItemLayout = {
                labelCol: {span: 5},
                wrapperCol: {span: 18}
            };
            const detail_info = this.props.detailInfo;
            return (
                <Form layout="horizontal">
                    <FormItem label="角色名称:" {...formItemLayout}>
                        <Input disabled maxLength={8} placeholder={detail_info.role_name}/>
                    </FormItem>
                    <FormItem label="选择用户:" {...formItemLayout}>
                        {/*穿梭框*/}
                        <Transfer
                            listStyle=
                            dataSource={this.props.mockData}
                            showSearch
                            titles={['待选用户', '已选用户']}
                            searchPlaceholder='输入用户名'
                            filterOption={this.filterOption}
                            targetKeys={this.props.targetKeys}
                            onChange={this.handleChange}
                            render={item => item.title}
                        />
                    </FormItem>
                </Form>
            )
        }
    }
    RoleAuthForm = Form.create({})(RoleAuthForm);