Skip to content

r-uploader

r-uploader 文件上传,用于将本地的图片或文件上传至服务器,并在上传过程中展示预览图和上传进度。目前 Uploader 组件不包含将文件上传至服务器的接口逻辑,该步骤需要自行实现。

示例

vue
<template>
  <view class="content" style="padding: 0px; background-color: transparent">
    <r-config-provider>
      <r-collapse v-model:value="activeName2" accordion @change="onChange">
        <r-collapse-item title="基础用法" name="1">
          <r-uploader v-model:value="fileList" :after-read="afterRead" />
        </r-collapse-item>
        <r-collapse-item title="文件预览" name="2">
          <r-uploader v-model:value="fileList" :after-read="afterRead" />
        </r-collapse-item>
        <r-collapse-item title="上传状态" name="3">
          <r-uploader v-model:value="fileList" :after-read="afterRead" />
        </r-collapse-item>
        <r-collapse-item title="限制上传数量" name="4">
          <r-uploader
            v-model:value="fileList"
            multiple
            :max-count="2"
            :after-read="afterRead"
          />
        </r-collapse-item>
        <r-collapse-item title="限制上传大小" name="5">
          <r-uploader
            v-model:value="fileList"
            multiple
            :max-size="500 * 1024"
            :after-read="afterRead"
            @oversize="onOversize"
          />
        </r-collapse-item>
        <r-collapse-item title="自定义上传样式" name="6">
          <view style="min-height: 80px">
            <r-uploader v-model:value="fileList" :after-read="afterRead">
              <r-button icon="plus" type="primary">上传文件</r-button>
            </r-uploader>
          </view>
        </r-collapse-item>

        <r-collapse-item title="自定义预览样式" name="7">
          <r-uploader v-model:value="fileList" :after-read="afterRead">
            <template #previewCover="file">
              <view class="preview-cover">{{ file.item.name }}</view>
            </template>
          </r-uploader>
        </r-collapse-item>
        <r-collapse-item title="自定义预览大小" name="8">
          <r-uploader
            v-model:value="fileList"
            :after-read="afterRead"
            :preview-size="[120, 80]"
          />
        </r-collapse-item>

        <r-collapse-item title="上传前置处理" name="9">
          <r-uploader
            v-model:value="fileList"
            :before-read="beforeRead"
            :after-read="afterRead"
          />
        </r-collapse-item>
        <r-collapse-item title="禁用文件上传" name="10">
          <r-uploader
            v-model:value="fileList"
            disabled
            :after-read="afterRead"
          />
        </r-collapse-item>

        <r-collapse-item title="开启覆盖上传" name="11">
          <r-uploader
            v-model:value="fileList"
            reupload
            :after-read="afterRead"
          />
        </r-collapse-item>
      </r-collapse>
    </r-config-provider>
    <r-toast ref="toastRef"></r-toast>
  </view>
</template>
<script setup>
import { ref } from "vue";
import useToast from "@/uni_modules/r-toast/components/r-toast/useToast";
const toastRef = ref(null);
const {
  showToast,
  showLoadingToast,
  showSuccessToast,
  showFailToast,
  closeToast,
} = useToast(toastRef);
const fileList = ref([]);
const uploadFilePromise = (url) => {
  console.log("url", url);
  return new Promise((resolve, reject) => {
    //换成自己的上传接口
    uniCloud.uploadFile({
      filePath: url,
      cloudPath: "test-" + new Date().getTime() + ".png",
      onUploadProgress: function (progressEvent) {
        console.log(progressEvent);
        var percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
      },
      success(e) {
        console.log("success e", e);
        resolve(e.fileID);
      },
      fail(e) {
        console.log("fail e", e);
        reject(e);
      },
      complete() {},
    });
  });
};
const getFile = (t) => {
  console.log("t", t);
  return "1";
};

const beforeRead = (file) => {
  if (("" + file.url).indexOf(".png") < 0) {
    showToast("请上传png格式文件");
    return false;
  }

  return true;
};
const afterRead = async (file) => {
  console.log("file", file);

  let lists = [].concat(file);
  console.log("event.file", file, lists);
  let fileListLen = fileList.value.length;
  lists.map((item) => {
    if (item.index == -1) {
      fileList.value.push({
        ...item,
        status: "uploading",
        message: "上传中",
      });
    } else {
      fileList.value[item.index] = {
        ...item,
        status: "uploading",
        message: "上传中",
      };
    }
  });

  for (let i = 0; i < lists.length; i++) {
    try {
      const result = await uploadFilePromise(lists[i].url);
      console.log("result", result, lists[i].index);
      let item = fileList.value[fileListLen];
      if (lists[i].index === 0 || lists[i].index != -1) {
        fileList.value = fileList.value.map((t, index) => {
          if (index == lists[i].index) {
            return {
              ...t,
              status: "success",
              message: "",
              url: result,
            };
          }
          return t;
        });
      } else {
        fileList.value.splice(
          lists[i].index != -1 ? lists[i].index : fileListLen,
          1,
          Object.assign(item, {
            status: "success",
            message: "",
            url: result,
          })
        );
        fileListLen++;
      }

      console.log("fileList", fileList.value);
    } catch (error) {}
  }
};

const onOversize = (file) => {
  console.log(file);
  showToast("文件大小不能超过 500kb");
};
const activeName2 = ref(["1"]);

const onChange = (name) => {
  if (["1", "4", "5", "6", "8", "9", "10"].includes(name)) {
    fileList.value = [];
  } else if (name == 2) {
    fileList.value = [
      {
        url: "https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg",
      },
    ];
  } else if (name == 11) {
    fileList.value = [
      {
        url: "https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg",
      },
    ];
  } else if (name == 3) {
    fileList.value = [
      {
        url: "https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg",
        status: "uploading",
        message: "上传中...",
      },
      {
        url: "https://fastly.jsdelivr.net/npm/@vant/assets/tree.jpeg",
        status: "failed",
        message: "上传失败",
      },
    ];
  } else if (name == 7) {
    fileList.value = [
      {
        url: "https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg",
        name: "文件名称",
      },
    ];
  }
};
</script>
<style lang="scss">
.preview-cover {
  position: absolute;
  bottom: 0;
  box-sizing: border-box;
  width: 100%;
  padding: 4px;
  color: #fff;
  font-size: 12px;
  text-align: center;
  background: rgba(0, 0, 0, 0.3);
}
</style>

API

Props

名称说明类型默认值可选值
value已上传的文件列表Array[]-
accept接受的文件类型,file 只支持 H5(只有微信小程序才支持把 accept 配置为 all、media)Stringimageall media image file video
capture图片或视频拾取模式,当 accept 为 image 类型时,设置 capture 为 camera 可以直接调起摄像头String | Array[ablum,camera]camera ablum
compressed当 accept 为 video 时生效,是否压缩视频,默认为 trueBooleantruefalse
camera当 accept 为 video 时生效Stringbackfront back
sizeTypeoriginal 原图,compressed 压缩图,默认二者都有,H5 无效Array[original,compressed ]original compressed
maxDuration当 accept 为 video 时生效,拍摄视频最长拍摄时间,单位秒Number60-
name标识符,通常为一个唯一的字符串或数字,可以在回调函数的第二项参数中获取Number | String--
previewSize预览图和上传区域的尺寸,默认单位为 pxString | Number | Array80-
previewImage是否在上传完成后展示预览图Booleantruefalse
previewFullImage是否在点击预览图后展示全屏图片预览Booleantruefalse
multiple是否开启图片多选Booleanfalsetrue
disabled是否禁用文件上传Booleanfalsetrue
readonly是否将上传区域设置为只读状态Booleanfalsetrue
deletable是否展示删除按钮Booleantruefalse
reupload是否开启覆盖上传,开启后会关闭图片预览Booleanfalsetrue
showUpload是否展示上传区域Booleantruefalse
afterRead文件读取完成后的回调函数Function--
beforeRead文件读取前的回调函数Function--
maxSize文件大小限制,单位为byteNumber |String | Function2 _ 1024 _ 1024-
maxCount文件上传数量限制Number5-
uploadText上传区域文字提示String--
imageFit预览图裁剪模式,可选值见 r-image 组件Stringcover
uploadIcon上传区域图标名称,等同于 r-icon 组件的 name 属性Stringphotograph
uploadIconPrefix上传区域图标的前缀类名,等同于 r-icon 组件的 prefix 属性Stringvan-iconiconfont
themeNamer-theme的主题名称Stringdefault-

Events

名称说明参数
oversize文件大小超过限制时触发files
clickUpload点击上传区域时触发event
delete点击删除后触发item,detail
update:value数据变化后触发files
error文件选择错误时触发error
afterRead读取后触发files

Slots

名称说明参数
default自定义上传区域-
previewDelete自定义删除按钮-
previewCover自定义覆盖在预览区域上方的内容item,index

更多组件,请前往rainui