从零开始,搭建一个简单的购物平台(六)

简介: 从零开始,搭建一个简单的购物平台(六)

从零开始,搭建一个简单的购物平台(五):https://blog.csdn.net/time_____/article/details/105437534

项目源码(持续更新):https://gitee.com/DieHunter/myCode/tree/master/shopping


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


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


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

1.gif

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>
    );
  }
}

然后我们在某个页面引入该组件试试效果

1.gif


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


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

1.png


有几个注意点,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={{ width: 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>
    );
  }
}


最后,我们请求服务端试一试

1.gif


总结


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


相关文章
|
运维 前端开发 NoSQL
从零开始,手把手教你实现一个高效的OA会议系统
从零开始,手把手教你实现一个高效的OA会议系统
167 0
|
前端开发 数据管理
从零开始,搭建一个简单的购物平台(五)
从零开始,搭建一个简单的购物平台(五)
318 1
从零开始,搭建一个简单的购物平台(五)
|
前端开发 数据库连接 数据库
从零开始,搭建一个简单的购物平台(二)
从零开始,搭建一个简单的购物平台(二)
187 1
从零开始,搭建一个简单的购物平台(二)
|
前端开发 测试技术 数据库
从零开始,搭建一个简单的购物平台(三)
从零开始,搭建一个简单的购物平台(三)
102 1
从零开始,搭建一个简单的购物平台(三)
|
前端开发 JavaScript 数据库
从零开始,搭建一个简单的购物平台(十五)前端商城部分
从零开始,搭建一个简单的购物平台(十五)前端商城部分
218 1
从零开始,搭建一个简单的购物平台(十五)前端商城部分
|
前端开发
从零开始,搭建一个简单的购物平台(十六)前端商城部分
从零开始,搭建一个简单的购物平台(十六)前端商城部分
236 1
从零开始,搭建一个简单的购物平台(十六)前端商城部分
|
前端开发 数据库
从零开始,搭建一个简单的购物平台(七)
从零开始,搭建一个简单的购物平台(七)
150 0
从零开始,搭建一个简单的购物平台(七)
|
缓存 前端开发 数据库
从零开始,搭建一个简单的购物平台(四)
从零开始,搭建一个简单的购物平台(四)
135 0
从零开始,搭建一个简单的购物平台(四)
|
前端开发 数据库
从零开始,搭建一个简单的购物平台(八)
从零开始,搭建一个简单的购物平台(八)
163 0
从零开始,搭建一个简单的购物平台(八)
|
前端开发 JavaScript NoSQL
从零开始,搭建一个简单的购物平台(一)
从零开始,搭建一个简单的购物平台(一)
447 0
从零开始,搭建一个简单的购物平台(一)