美文网首页Web前端之路
ant-design customRequest自定义上传组件封

ant-design customRequest自定义上传组件封

作者: hold_baby | 来源:发表于2020-09-12 10:37 被阅读0次

    通过覆盖默认的上传行为,可以自定义自己的上传实现

    自定义的上传步骤

    • 调用预上传接口拿到上传地址与对象存储id
    • 使用put方法上传文件并带上存储id
    // 定义变量与方法, 方便描述
    const PRE_UPLOAD_URL // 预上传地址
    const UPLOAD_URL // 上传地址
    const objectID // 对象存储id
    const parseSearchString // 格式化url参数为对象的方法
    const toSearchString // 格式化对象为url参数的方法
    const getUrlByObjectID // 通过对象存储id拿url的方法
    const uuid // 生成唯一id的方法
    
    const Uploader = ({ onChange, value, children, ...props }) => {
      // 初始化初始值
      useEffect(() => {
        if (!value) return;
    
        const fileList = value.map((fileInfo) => {
          const { name, objectID, } = fileInfo
          const uid = uuid()
          return {
            status: "done", // 初始值文件的状态
            url: getUrlByObjectID(fileInfo.objectID), // 获取显示图片的url
            uid, // 内部唯一id
            name, // 文件名称
            objectID
          }
        });
        // 更新
        onChange && onChange(fileList);
      }, []);
    
      return (
        <Upload
          action={(file) => {
            return new Promise((c, e) => {
              // 请求预上传地址,拿到上传地址与id
              axios.get(PRE_UPLOAD_URL).then(
                (res) => {
                  const data = res.data;
                  const { UPLOAD_URL, objectID } = data;
                  const [base, queryStr] = UPLOAD_URL.split("?");
                  const query = {
                    objectID, // 把id通过query的方式传递
                    ...parseSearchString(queryStr), 
                  };
                  c(`${base}${toSearchString(query)}`);
                },
                () => {
                  e("上传失败");
                },
              );
            });
          }}
          customRequest={(e) => {
            const [url, queryStr] = e.action.split("?");
            const query = parseSearchString(queryStr);
            // 取出对象存储id
            const { objectID = "",  ...other } = query;
            const file = e.file;
            const name = file.name; // 文件名字
    
            组装上传地址
            const action = `${url}${toSearchString(other)}`;
            axios
              .put(action, file, {
                // 显示进度
                onUploadProgress: (ev) => {
                  const percent = ((ev.loaded / ev.total) * 100) | 0;
                  e.onProgress(
                    {
                      percent,
                    },
                    file,
                  );
                },
              })
              .then(
                () => {
                  const url = getUrlByObjectID(objectID)
                  // 上传成功
                  e.onSuccess(
                    {
                      objectID,
                      name,
                      url,
                    },
                    file,
                  );
                },
                (res) => {
                  e.onError(res);
                },
              );
          }}
          onChange={({ event, fileList }) => {
            if (event && event.percent === 100) {
              // 这里100%后不能正常拿到上传的对象 需要延迟处理
              setTimeout(() => {
                // 上面onSuccess传递的参数会被包裹在response中
                let value = fileList.map(({ response, uid }) => ({ ...response, uid }));
                onChange && onChange(value);
              }, 1000);
            }
          }}
          method="put"
          {...props} 
          />
      );
    };
    

    在form中使用

    <Form.Item name="upload" label="上传图片">
      <Uploader listType="picture">
        <Button>
           <UploadOutlined /> 上传图标
         </Button>
       </Uploader>
    </Form.Item>
    

    相关文章

      网友评论

        本文标题:ant-design customRequest自定义上传组件封

        本文链接:https://www.haomeiwen.com/subject/xjqmektx.html