react自定义dialog弹窗--插槽功能--穿插redux一些知识

6 篇文章 0 订阅
1 篇文章 0 订阅

 

效果图如上:

1.点击按钮出现弹窗,点击弹窗的x按钮隐藏弹窗;

2.插槽可以是组件,可以是直接写div等代码;

3.确认保存按钮功能没做,主要是为了布局效果而已;

 直接看代码:

components/App.js

import React from 'react';
import PopContainer from '../containers/PopContainer'
import Slot from '../containers/SlotContainer'
import Slot1 from './slot1'
import Slot2 from './slot2'
import Slot3 from './slot3'

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            left: 'left',
            right: 'right',
            center: 'center',
            show: false,
        }
    }
    showing = (show) => {
        this.setState({
            show,
        })
    }
    render() {
        return (
            <div>
                <button onClick={()=>{
                    this.setState({
                        show: !this.state.show,
                    })
                }}>弹窗</button>
                <PopContainer show={this.state.show} showing={this.showing.bind(this)}>
                    <Slot></Slot>
                    <Slot1 left={this.state.left}></Slot1>
                    <Slot2 center={this.state.center}></Slot2>
                    <Slot3 right={this.state.right}></Slot3>
                </PopContainer>
            </div>
        );
    };
}

App.propTypes = {};

export default App;

 

comnponents/Pop.js

import React from 'react';
import { Fragment, Component } from 'react';
import './index.scss'
import { Button } from 'antd'
import {
    CloseOutlined,
} from '@ant-design/icons';

class Pop extends Component {
    constructor(props) {
        super(props);
        this.state = {
            popTitle: '弹窗',
            show: false,
        }
        this.renderChild = this.renderChild.bind(this)
    }

    componentDidCatch =() =>{
    }

    render() {
        return (
            <Fragment>
            {
                this.props.show ?
                <div className="pop-wrap">
                    <div className="pop-header">
                        <span className="left">{this.state.popTitle}</span>
                        <CloseOutlined onClick={() => {
                            this.props.showing(false);
                        }}/>
                    </div>
                    <div className="pop-content">
                        {this.props.show+''}
                        {/* {this.props.children} */}
 
                        {Array.isArray(this.props.children) ?
                            this.props.children.map((child) => {
                                return this.renderChild(child)
                            }) : this.props.children && this.renderChild(this.props.children)}
                    </div>
                    <div className="pop-footer">
                        <Button type="primary">确认</Button>
                        &nbsp;&nbsp;&nbsp;&nbsp;
                        <Button>保存</Button>
                    </div>
                </div>
                : null
            }
            </Fragment>
        )
    }

    renderChild(child) { // 控制内容的分发
        if (child.props.left) {
            return <div className="left" key="left">{child}</div>
        } else if (child.props.right) {
            return <div className="right" key="right">{child}</div>
        } else if (child.props.center) {
            return <div className="center" key="center">{child}</div>
        }
        return child;
    }

};

export default Pop;

containers/PopContainer.js

import { connect } from 'react-redux'
import Pop from '../components/Pop'

const mapStateToProps = (state) => {
    return {

    }
}

const mapDispatchToProps = (dispatch) => {
    return {
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Pop)

components/slot.js

import React from 'react';
import PropTypes from 'prop-types';
import 'antd/dist/antd.css'
import { Form, Input, Button, Checkbox, Table } from 'antd';
const layout = {
  labelCol: {
    span: 28,
  },
  wrapperCol: {
    span: 116,
  },
};
const tailLayout = {
  wrapperCol: {
    offset: 88,
    span: 186,
  },
};

class slot extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      tabledata: []
    };
    this._tabledata = [];
  }

  componentDidMount() {
    this.setState({
      tabledata: this.props.dataSource
    });
  }


  render = () => {
    const onFinish = (values) => {
      console.log('Success:', values);
      let val = this.props.setUsername(values);
      this.setState({
        loading: true
      })
      Promise.resolve(val).then(() => {
        Object.assign(val, { key: this.state.tabledata.length })
        this._tabledata.push(val);
        setTimeout(() => {
          this.setState({
            loading: false,
            tabledata: [...this.props.dataSource, ...this._tabledata]
          })
        }, 100);

      })
    };

    const onFinishFailed = (errorInfo) => {
      console.log('Failed:', errorInfo);
    };

    return (
      <>
        <Form
          {...layout}
          name="basic"
          initialValues={{
            remember: true,
          }}
          onFinish={onFinish}
          onFinishFailed={onFinishFailed}
        >
          <Form.Item
            label="Username"
            name="username"
            rules={[
              {
                required: true,
                message: 'Please input your username!',
              },
            ]}
          >
            <Input />
          </Form.Item>

          <Form.Item
            label="Password"
            name="password"
            rules={[
              {
                required: true,
                message: 'Please input your password!',
              },
            ]}
          >
            <Input.Password />
          </Form.Item>

          <Form.Item
            label="Age"
            name="age"
            rules={[
              {
                required: true,
                message: 'Please input your age!',
              },
            ]}
          >
            <Input />
          </Form.Item>

          <Form.Item
            label="Address"
            name="address"
            rules={[
              {
                required: true,
                message: 'Please input your address!',
              },
            ]}
          >
            <Input />
          </Form.Item>

          <Form.Item {...tailLayout} name="remember" valuePropName="checked">
            <Checkbox>Remember me</Checkbox>
          </Form.Item>

          <Form.Item {...tailLayout}>
            <Button type="primary" htmlType="submit">
              Submit
              </Button>
          </Form.Item>
        </Form>
        <Table dataSource={this.state.tabledata} columns={this.props.columns} loading={this.state.loading} />
      </>
    );
  };
}

slot.propTypes = {};

export default slot;

containers/SlotContainer.js

import { connect } from 'react-redux'
import Slot from '../components/slot'

const dataSource = [
  {
    key: '--',
    username: '晋安',
    age: 32,
    address: '北京',
  },
];

const columns = [
  {
    title: '姓名',
    dataIndex: 'username',
    key: 'username',
  },
  {
    title: '年龄',
    dataIndex: 'age',
    key: 'age',
  },
  {
    title: '住址',
    dataIndex: 'address',
    key: 'address',
  },
];
const mapStateToProps = (state) => {
  return {
    dataSource,
    columns,
  }
}

const setUsername = text => ({
  type: 'username',
  ...text,
})

const mapDispatchToProps = (dispatch) => {
  return {
    setUsername: text => dispatch(setUsername(text)),
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Slot)

slot1.js,slot2.js,slot3.js

slot1.js
import React from 'react';
import PropTypes from 'prop-types';

class slot1 extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (
            <div>
                <div left="true">{this.props.left}</div>
                <ul>
                    <li>react</li>
                    <li>redux</li>
                    <li>react-redux</li>
                </ul>
            </div>
        );
    }
}

slot1.propTypes = {};

export default slot1;


slot2.js
import React from 'react';
import PropTypes from 'prop-types';

class slot2 extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <div center="true">{this.props.center}</div>
            </div>
        );
    }
}

slot2.propTypes = {};

export default slot2;


slot3.js
import React from 'react';
import PropTypes from 'prop-types';

class slot3 extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <div right="true">{this.props.right}</div>
            </div>
        );
    }
}

slot3.propTypes = {};

export default slot3;

布局代码index.scss

.pop-wrap {
    display: flex;
    flex-direction: column;
    padding: 0 15px;
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    transform: translateY(-50%);
    margin: auto;
    z-index: 2;
    width: 80vw;
    min-height: 680px;
    border: 1px solid #C8C8C8;
    border-radius: 5px;
    &.hide {
        display: none;
    }
}
  
  .pop-header {
    height: 40px;
    flex: 0 0 40px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #C8C8C8;
  }

  .pop-content {
    flex: 1;
    margin-top: 10px;
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    &>form {
        width: 100%;
        &+div {
            width: 100%;
        }
    }
    .left, .right, .center {
        flex: 1;
        text-align: center;
    }
  }
  
  .pop-footer {
    height: 40px;
    flex: 0 0 40px;
    display: flex;
    align-items: center;
    border-top: 1px solid #C8C8C8;
    flex-direction: row-reverse;
  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值