zoukankan      html  css  js  c++  java
  • 从零开始,搭建一个简单的购物平台(六)

    从零开始,搭建一个简单的购物平台(五):https://blog.csdn.net/time_____/article/details/105437534
    项目源码(持续更新):https://gitee.com/DieHunter/myCode/tree/master/shopping

    第四篇文章中实现了服务端的文件上传以及添加用户的后端功能,并进行了测试,这篇文章主要实现前端上传头像和添加用户的功能

    首先我们引入antd中的文件上传组件,并将其封装到我们的组件中

    • 我们限制用户只能上传一张图片,其中上传组件中的action表示上传的路径,也就是我们在第四篇中的测试上传文件地址,name是文件标识名,data是传的参数,这里我们是用的token

    import React from "react";
    import { Upload,  message } from "antd";
    import { PlusOutlined } from "@ant-design/icons";
    import config from "../../config/config";
    let {
      UploadName,
      Agreement,
      BaseUrl,
      ServerPort,
      Path,
      UploadKey,
      StorageName,
    } = config;
    export default class UpdataPic extends React.Component {
      state = {
        fileList: [],
      };
      
      
      handleChange = ({ fileList, file }) => {
        this.setState({ fileList });
        if (file["response"] && file.status == "done") {
          let res = file["response"];
          message.success(res.msg);
        }
        if (file["status"] == "removed") {
          
        }
      };
      render() {
        const { fileList } = this.state;
        const uploadButton = (
          <div>
            <PlusOutlined />
            <div className="ant-upload-text">上传头像</div>
          </div>
        );
        return (
          <div className="clearfix">
            <Upload
              action={Agreement + BaseUrl + ServerPort + Path + UploadName.headPic}
              name={UploadKey.headKey}
              listType="picture-card"
              fileList={fileList}
              onChange={this.handleChange}
              data={{ token: this.$utils.getStorage(StorageName.token) }}
            >
              {fileList.length >= 1 ? null : uploadButton}
            </Upload>
          </div>
        );
      }
    }
    
    
    • 然后我们在某个页面引入该组件试试效果

    上传功能实现后,我们就可以开始实现添加用户了

    • 新增用户,我打算放到右边的抽屉组件中,也就是Drawer组件,将form表单嵌入至抽屉中(修改用户和新增用户有着类似之处,我们做修改用户信息直接在新增用户Drawer中赋予form初始值即可

    • 有几个注意点,1.antd的form需要使用React.createRef()将组件加载。2.表单数据赋予初始值时,需要调表单的this.formRef.current.setFieldsValue()方法,然而这里有个坑,当Drawer组件显示时,form组件还未载入,这时如果直接赋值,就会因异步导致赋值不成功,解决方法(官方给的处理方式是用redux全局管理,我这里是用生命周期函数解决的):首先在Drawer组件中启用预加载功能(forceRender,预渲染 Drawer 内元素),然后在生命周期(componentDidUpdate)中获取state中的值,调用this.formRef.current.setFieldsValue()即可(修改用户信息与此相同)
    import React from "react";
    import Mail from "../../config/mail";
    import {
      Drawer,
      Form,
      Button,
      Col,
      Row,
      Input,
      Select,
      Radio,
      Cascader,
      message,
    } from "antd";
    import config from "../../config/config";
    import City from "../../config/city";
    import UpdataPic from "../updata/updata";
    const { ServerApi, StorageName, FilePath } = config;
    const { Option } = Select;
    
    export default class ListDrower extends React.Component {
      formRef = React.createRef();
      state = {
        visible: false,
        record: {},
      };
      componentDidMount() {
        this.props.onDrowerRef(this);
      }
      componentDidUpdate() {
        this.formRef.current.setFieldsValue(this.state.record);
      }
    
      showDrawer = () => {//显示Drawer
          this.setState({
            formType: "add",
            visible: false,
            record: {
              sex: "man",
              userType: "user",
              mailurl: "@qq.com",
            },
          });
        this.setState({
          visible: true,
        });
      };
      onClose = () => {//隐藏Drawer
        this.formRef.current.resetFields();
        this.setState({
          visible: false,
          record: null,
        });
      };
      getPic = (data) => {//上传头像后刷新表单头像信息
        this.formRef.current.setFieldsValue({
          headPic: data.headPath,
        });
      };
      delPic = () => {//删除头像后同时删除表单图片信息
        this.formRef.current.setFieldsValue({
          headPic: null,
        });
      };
      sendData(val) {//提交用户信息
        val.token = this.$utils.getStorage(StorageName.token);
        let data = this.$crypto.setCrypto(val);
        let _t = this;
        this.$axios
          .post(ServerApi.user.addUser, { crypto: data })
          .then((res) => {
            switch (res.result) {
              case 1:
                message.success(res.msg);
                _t.onClose();
                _t.props.getUserList();
                break;
              case 0:
                message.warning(res.msg);
                break;
              default:
                // message.warning(res.msg);
                break;
            }
          })
          .catch((err) => {
            message.error("操作失败");
          });
      }
      render() {
        return (
          <Drawer
            title="新增用户"
            width={720}
            onClose={this.onClose}
            visible={this.state.visible}
            forceRender //加上预加载,防止表单异步生成,导致this.formRef.current为空
            bodyStyle={{ paddingBottom: 80 }}
            footer={
              <div
                style={{
                  textAlign: "right",
                }}
              >
                <Button onClick={this.onClose} style={{ marginRight: 20 }}>
                  取消
                </Button>
              </div>
            }
          >
            <Form
              layout="vertical"
              hideRequiredMark
              ref={this.formRef}
              onFinish={this.sendData.bind(this)}
            >
              <Row gutter={16}>
                <Col span={10}>
                  <Form.Item name="headPic" label="头像">
                    <UpdataPic
                      onUpdateRef={(child) => {
                        this.updateChild = child;
                      }}
                      picTarget={this.getPic}
                      picDelete={this.delPic}
                    ></UpdataPic>
                  </Form.Item>
                </Col>
                <Col span={10}>
                  <Form.Item
                    name="userType"
                    label="用户类型"
                    rules={[{ required: true, message: "请选择用户类型" }]}
                  >
                    <Radio.Group buttonStyle="solid">
                      <Radio.Button value="admin">管理员</Radio.Button>
                      <Radio.Button value="user">用户</Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={16}>
                <Col span={12}>
                  <Form.Item
                    name="username"
                    label="用户名"
                    rules={[{ required: true, message: "请输入用户名" }]}
                  >
                    <Input placeholder="请输入用户名" allowClear />
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item
                    name="password"
                    label="密码"
                    rules={[{ required: true, message: "请输入密码" }]}
                  >
                    <Input.Password
                      type="password"
                      placeholder="请输入密码"
                      allowClear
                    />
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={16}>
                <Col span={5}>
                  <Form.Item
                    name="sex"
                    label="性别"
                    rules={[{ required: true, message: "请选择性别" }]}
                  >
                    <Radio.Group buttonStyle="solid">
                      <Radio.Button value="man">男</Radio.Button>
                      <Radio.Button value="woman">女</Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={16}>
                  <Form.Item label="邮箱">
                    <Input.Group compact>
                      <Form.Item
                        name="mailaddress"
                        rules={[{ required: true, message: "请输入正确邮箱" }]}
                      >
                        <Input defaultValue="" allowClear />
                      </Form.Item>
                      <Form.Item
                        name="mailurl"
                        rules={[{ required: true, message: "请选择邮箱类型" }]}
                      >
                        <Select onChange={this.changeMail} style={{  150 }}>
                          {(() => {
                            return Mail.address.map((item) => {
                              return (
                                <Option key={item.mail} value={item.mail}>
                                  {item.mail}
                                </Option>
                              );
                            });
                          })()}
                        </Select>
                      </Form.Item>
                    </Input.Group>
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={20}>
                <Col span={16}>
                  <Form.Item label="收货地址" required={false}>
                    <Input.Group compact>
                      <Form.Item
                        name="alladdress"
                        // rules={[{ required: true, message: "请选择收货地址" }]}
                      >
                        <Cascader options={City} placeholder="请选择收货地址" />
                      </Form.Item>
                      <Form.Item
                        name="address"
                        // rules={[{ required: true, message: "请填写收货地址" }]}
                      >
                        <Input placeholder="请输入详细地址" allowClear />
                      </Form.Item>
                    </Input.Group>
                  </Form.Item>
                </Col>
              </Row>
              <Row gutter={16}>
                <Col span={24}>
                  <Form.Item name="descript" label="个性签名">
                    <Input.TextArea rows={4} placeholder="个性签名" />
                  </Form.Item>
                </Col>
              </Row>
              <Form.Item>
                <Button
                  type="primary"
                  htmlType="submit"
                  className="login-form-button"
                >
                  提交
                </Button>
              </Form.Item>
            </Form>
          </Drawer>
        );
      }
    }
    
    • 最后,我们请求服务端试一试

    总结

    React是一个基于view显示层实现的dom优化框架,其对全局状态管理插件redux是将部分共享变量全局化,就相当于在原生window作用域中定义全局变量,虽然有一定的便捷,但是能不用的地方,最好是少用

  • 相关阅读:
    Flask目录结构
    RHSA-2019:1880-低危: curl 安全和BUG修复更新 及 RHSA-2019:1884-中危: libssh2 安全更新
    ELK+Logback进行业务日志分析查看
    Maven编译过程中出现的问题
    Zabbix监控服务器磁盘I/O
    创建readonly只读用户脚本
    Zabbix监控多个JVM进程
    redis命令
    docker配置Nginx
    docker基本命令
  • 原文地址:https://www.cnblogs.com/HelloWorld-Yu/p/13514436.html
Copyright © 2011-2022 走看看