vant图片上传压缩

文件上传组件

<template>
  <van-uploader v-model="fileListed" multiple :after-read="afterRead" :max-count="maxCount" :before-read="beforeRead" @delete="deleteUpload" />
</template>
<script>
import {
    
     defineComponent, reactive, toRefs, computed, ref } from 'vue';
import axios from 'axios';
import {
    
     Dialog, Notify } from 'vant';
import Compressor from 'compressorjs';
export default defineComponent({
    
    
  name: 'uploader',
  components: {
    
    
    [Dialog.Component.name]: Dialog.Component,
    [Notify.Component.name]: Notify.Component
  },
  props: {
    
    
    fileList: {
    
    
      type: Array,
      default: []
    },
    maxCount: {
    
    
      type: Number,
      default: -1
    },
    maxSize: {
    
    
      type: Number,
      default: 5
    }
  },
  emits: ['uploadSuccess', 'uploadDetele'],
  setup(props, {
     
      emit }) {
    
    
    const state = reactive({
    
    
      excelUrl: import.meta.env.VITE_MODE_PATH + '你的文件上传api',
      headers: {
    
    
        token: JSON.parse(localStorage.getItem('token'))
      }
    });
    const fileListed = ref([]);
    computed(() => {
    
    
      let arr = JSON.parse(JSON.stringify(props.fileList));
      if (arr.length > 0) {
    
    
        arr.map((item) => {
    
    
          if (item.url.indexOf(window.$config.IMAGEURL) == -1) {
    
    
            item.url = window.$config.IMAGEURL + item.url;
          }
        });
      }
      fileListed.value = arr;
      return;
    });
    //上传状态
    const afterRead = async (file) => {
    
    
      // file.status = "uploading";
      // file.message = "上传中...";
      let formData = new FormData();
      if (file.file.size > 1024 * 300) {
    
    
        let img = file.file;
        if (!['jpeg', 'jpg'].includes(img.type)) {
    
    
          img = await ConvertImage(img); //转陈jpeg格式的file
          compressorImage(img, 'file', 0.9).then((f) => {
    
    
            if (f.size >= props.maxSize * 1024 * 1024) {
    
    
              $Toast(`文件大小不能超过${
      
      props.maxSize}M`);
            } else {
    
    
              formData.append('file', f);
              uploadFile(formData);
            }
          });
        }
      } else {
    
    
        formData.append('file', file.file);
        uploadFile(formData);
      }
    };
    const uploadFile = (formData) => {
    
    
      const config = {
    
    
        headers: {
    
    
          'Content-Type': 'multipart/form-data',
          token: state.token
        }
      };
      axios.post(state.excelUrl, formData, config).then((res) => {
    
    
        // 根据自己的后端逻辑进行判断
        if (res.data.code == 1) {
    
    
          Notify({
    
    
            type: 'success',
            message: '图片上传成功'
          });
          emit('uploadSuccess', res.data.data);
        } else {
    
    
          $Toast('文件服务异常,请联系管理员!');
        }
      });
    };
    // 返回布尔值
    const beforeRead = (file) => {
    
    
      if (file.type == 'image/jpeg' || file.type == 'image/png') {
    
    
        // console.log(state.fileList)
        return true;
      } else {
    
    
        $Toast('请上传 jpeg/png 格式图片');
        return false;
      }
    };
    //删除
    const deleteUpload = (file, detail) => {
    
    
      Dialog.confirm({
    
    
        title: '删除',
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        message: '是否确认删除此图片'
      })
        .then(() => {
    
    
          emit('uploadDetele', detail.index);
          Notify({
    
     type: 'success', message: '删除成功' });
          // resolve(true)
        })
        .catch((error) => {
    
    
          Notify({
    
    
            message: '已取消删除',
            color: '#999999',
            background: '#F5F5F5'
          });
          // reject(error)
        });
    };
    /**
     * @param image 图片
     * @param backType 需要返回的类型blob,file
     * @param quality 图片压缩比 0-1,数字越小,图片压缩越小
     * @returns
     */
    const compressorImage = (image, backType, quality) => {
    
    
      return new Promise((resolve, reject) => {
    
    
        new Compressor(image, {
    
    
          quality: quality || 0.8,
          success(result) {
    
    
            let file = new File([result], image.name, {
    
     type: image.type });
            if (!backType || backType == 'blob') {
    
    
              resolve(result);
            } else if (backType == 'file') {
    
    
              resolve(file);
            } else {
    
    
              resolve(file);
            }
          },
          error(err) {
    
    
            console.log('图片压缩失败---->>>>>', err);
            reject(err);
          }
        });
      });
    };
    //图片转为jpeg图片
    function ConvertImage(file) {
    
    
      return new Promise((resolve, reject) => {
    
    
        const fileName = file.name.substring(0, file.name.indexOf('.'));
        let reader = new FileReader(); //读取file
        reader.readAsDataURL(file);
        reader.onloadend = function (e) {
    
    
          let image = new Image(); //新建一个img标签(还没嵌入DOM节点)
          image.src = e.target.result; //将图片的路径设成file路径
          image.onload = function () {
    
    
            let canvas = document.createElement('canvas'),
              context = canvas.getContext('2d'),
              imageWidth = image.width,
              imageHeight = image.height,
              data = '';
            canvas.width = imageWidth;
            canvas.height = imageHeight;

            context.drawImage(image, 0, 0, imageWidth, imageHeight);
            data = canvas.toDataURL('image/jpeg');
            var newfile = dataURLtoFile(data, fileName + '.jpeg');
            resolve(newfile);
          };
        };
      });
    }
    // base64转file对象
    function dataURLtoFile(dataurl, filename) {
    
    
      let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
    
    
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, {
    
     type: mime }); //转成了jpeg格式
    }
    return {
    
    
      ...toRefs(state),
      afterRead,
      beforeRead,
      deleteUpload,
      fileListed
    };
  }
});
</script>
<style scoped>
:deep(.van-image__img) {
    
    
  object-fit: contain !important;
}
</style>

页面使用

<uploader :fileList="fileList" :maxCount="6" @uploadDetele="detaleApply" @uploadSuccess="uploadApply"></uploader>
const uploadApply = (res) => {
    
    
     state.fileList.push({
    
     url: res });
};
const detaleApply = (res) => {
    
    
     state.fileList.splice(res, 1);
};

猜你喜欢

转载自blog.csdn.net/weixin_49295874/article/details/130025542