封装uniapp原生图片上传组件和文件上传组件

一、图片上传 

 内容:通过对uniapp提供的文件上传组件进行二次封装

思路:将上传成功后获取接口返回的数据进行处理

注意:token,上传路径,父子组件之间传递的值是否一致

将组件命名为 image-upload

<template>
  <uni-file-picker
    v-if="!disabled"
    :auto-upload="true"
    :limit="limit"
    v-model="imageValue"
    fileMediatype="image"
    mode="grid"
    @select="select"
    @progress="progress"
    @success="success"
    @fail="fail"
    :title="'最多选择' + limit + '张图片'"
  />
<view v-else class="preview">
    <img
      v-for="(item, i) in imageValue"
@click="previewImage(item.url)"
      class="viewImg"
      :src="item.url"
      :key="i"
    />
  </view>
</template>

<script>
import { baseUrl } from "@/config"; // 默认路径
export default {
  props: {
    value: {
      default: "",
    },
    // 上传张数
    limit: {
      default: "9",
    },
 disabled: {
      default: false,
      // default: true,
    },
  },
  data() {
    return {
      imageValue: [],
    };
  },
  watch: {
    value: {
      handler(val, oval) {
        // 监听父组件的值,时并实时赋值给imageValue
        if (val && val != oval) {
          this.imageValue = [];
          let arr = val.split(",");
          if (arr) {
            arr.forEach((item) => {
              this.imageValue.push({
                url: item,
              });
            });
          }
        }
      },
      deep: true, //是否深度监听
      immediate: true, //是否监听初始值
    },
    imageValue: {
      handler(val, oval) {
        // 监听imageValue的值(删除图片,上传图片),并同步给父组件
        if (val.length >= 0) {
          let arr = [];
          val.forEach((item) => {
            arr.push(item.url);
          });
          const str = arr.join(",");
          this.$emit("input", str); // 同步给父组件
        }
      },
      deep: true, //是否深度监听
      immediate: true, //是否监听初始值
    },
  },
  methods: {
    updata(filePath) {
      const that = this;
      // const accessToken = uni.getStorageSync("Authorization") || null; //获取token
      uni.uploadFile({
        url: baseUrl + "api/App/CDN/UploadImg", // 上传路径
        filePath: filePath,
        header: {
          // 请求头,不需要可以不传
          // Authorization: `Bearer ${accessToken}`,
        },
        formData: {
          // 其他需要携带的参数,没有可以不传
          
        },
        success(res) {
          // 上传成功,返回值是后端返回的值,组件以json格式获取到值,所以需要转换成对象
          let response = JSON.parse(res.data);
          // console.log("=======上传图片完成======>", response);
          if (response.data.url != undefined) {
            // 判断上传成功与否,也可以通过状态码进行判断
            // 把后端返回的上传后的图片路径组装成字符串,传递给父组件
            let str;
            if (that.value) {
              str = that.value + "," + response.data.url;
            } else {
              str = response.data.url;
            }
            that.$emit("input", str); // 同步给父组件
            uni.showToast({
              title: "上传图片成功",
              duration: 2000,
            });
          } else {
            uni.showToast({
              title: "上传图片失败,请重试!",
              icon: "none",
              duration: 2000,
            });
          }
        },
        fail(err) {
          console.log("=======上传图片失败======>", err);
          uni.showToast({
            title: "上传图片失败,请重试!",
            icon: "none",
            duration: 2000,
          });
        },
      });
    },
    // 获取上传状态
    select(e) {
      // console.log("选择文件:", e);
      e.tempFilePaths.forEach((item) => {
        this.updata(item);
      });
    },
    // 获取上传进度
    progress(e) {
      console.log("上传进度:", e);
    },

    // 上传成功
    success(e) {
      console.log("上传成功");
    },
    // 上传失败
    fail(e) {
      console.log("上传失败:", e);
    },
previewImage(url) {
      // 预览图片
      uni.previewImage({
        urls: [url],
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.preview {
  display: grid;
  grid-template-columns: 240rpx 240rpx 240rpx;// 三列
  /* 设置间距 */
  grid-gap: 20rpx;
  .viewImg {
    width: 240rpx;
    height: 240rpx;
  }
}
</style>

 二、上传文件

 思路与上传图片一样

将上传文件组件命名为file-upload

<template>
  <uni-file-picker
    :limit="limit"
    v-model="filesValue"
    mode="grid"
    file-mediatype="all"
    :disabled="disabled"
    @select="select"
    @progress="progress"
    @success="success"
    @fail="fail"
    :del-icon="!disabled"
  >
    <uni-button v-if="disabled"></uni-button>
  </uni-file-picker>
</template>

<script>
import { baseUrl } from "@/config";

export default {
  props: {
    value: {
      default: "",
    },
    // 上传数
    limit: {
      default: "9",
    },
    disabled: {
      default: false,
    },
  },
  data() {
    return {
      filesValue: [],
    };
  },
  watch: {
    value: {
      handler(val, oval) {
        if (val && val != oval) {
          this.filesValue = [];
          let arr = val.split(",");

          if (arr) {
            arr.forEach((item) => {
              let name = item.split("/").pop(); // 文件名
              let extname = name.split(".")[1]; // 后缀名
              this.filesValue.push({
                url: item,
                name,
                extname,
              });
            });
          }
        }
      },
      deep: true, //是否深度监听
      immediate: true, //是否监听初始
    },
    filesValue: {
      handler(val, oval) {
        if (val.length > 0) {
          let arr = [];
          val.forEach((item) => {
            arr.push(item.url);
          });
          const str = arr.join(",");
          this.$emit("input", str);
        } else {
          this.$emit("input", "");
        }
      },
      deep: true, //是否深度监听
      immediate: true, //是否监听初始
    },
  },
  methods: {
    updata(filePath) {
      const that = this;
      // const accessToken = uni.getStorageSync("App-Token") || null; // 获取token
      uni.uploadFile({
        url: baseUrl + "api/App/CDN/UploadOffice", // 上传路径
        filePath: filePath,
        name: "file",
        header: {
          // Authorization: `Bearer ${accessToken}`,
        },
        // HTTP 请求中其他额外的 form data
        formData: {
        },
        success(res) {
          // 上传成功,返回值是后端返回的值,组件以json格式获取到值,所以需要转换成对象
          let response = JSON.parse(res.data);
          // console.log("=======上传文件完成======>", response);
          if (response.data.url != undefined) {
            // 判断上传成功与否,也可以通过状态码进行判断
            // 把后端返回的上传后的文件路径组装成字符串,传递给父组件
            let str;
            if (that.value) {
              str = that.value + "," + response.data.url;
            } else {
              str = response.data.url;
            }
            that.$emit("input", str); // 同步给父组件
            uni.showToast({
              title: "上传文件成功",
              duration: 2000,
            });
          } else {
            uni.showToast({
              title: "上传文件失败,请重试!",
              icon: "none",
              duration: 2000,
            });
          }
        },
        fail(err) {
          uni.showToast({
            title: "上传文件失败,请重试!",
            icon: "none",
            duration: 2000,
          });
        },
      });
    },
    // 获取上传状态
    select(e) {
      console.log("选择文件:", e);
      e.tempFilePaths.forEach((item) => {
        this.updata(item);
      });
    },
    // 获取上传进度
    progress(e) {
      console.log("上传进度:", e);
    },

    // 上传成功
    success(e) {
      console.log("上传成功");
    },

    // 上传失败
    fail(e) {
      console.log("上传失败:", e);
    },
  },
};
</script>

<style lang="scss" scoped></style>

三、使用

<template>
  <view>
    <view>
      <view>图片上传</view>
      <image-upload v-model="form.img" style="flex-grow: 1" />
    </view>
    <view>
      <view>文件上传</view>
      <file-upload v-model="form.file" style="flex-grow: 1" /> </view
    ><view><button @click="look">提交</button></view>
  </view>
</template>
<script>
export default {
  data() {
    return {
      form: {
        img: "",
        file: "",
      },
    };
  },
  methods: {
    look() {
      console.log(this.form);
    },
  },
};
</script>

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值