流浪のwolf

卷帝

导航

本地图片上传服务器返回在线地址接口 - file - input -修改头像-带预览功能- 然后使用cropperjs 进行裁剪

说明:上传的图片是 file 类型 ,核心就是获取图片文件(file类型的)

实现一:使用 vant2 的图片加载组件 ,选择文件后会触发afterRead方法 ,参数 file 就是文件列表filelist ,file.file 就是图片文件 ;

 async afterRead(file) {
      console.log("afterRead");
      // 以下是向后端识别图片接口传递file文件
      const formData = new FormData();
      formData.append("file", file.file); // 注意是传file  .raw
      const res = await getImageApi(formData);
      //   console.log(res);
      if (res.errno === 0) {
        this.$toast.success("上传成功");
      } else {
        return this.$toast.fail("上传失败");
      }
      this.imgSrc = `http://124.223.14.236:8060/${res.data.savePath}`;
      setItem("IMGSRC", `http://124.223.14.236:8060/${res.data.savePath}`);
      // console.log(this.imgSrc);
    },

 实现方式二:自己使用 input 输入框实现 type为file 类型 ;

 

 multiple 属性可以选择多个文件上传 ;
input 给click事件不行的,只能使用change事件,click点击的时候就会触发,change选择文件点击确定的时候才会触发 ; <!-- 隐藏的选择文件标签 -->
this.$refs.imgFile.click() 模拟了点击input输入框事件 ;
    <!-- multiple 属性可以选择多个文件上传 -->
    <input type="file" name="" id="" ref="imgFile" @change="changeFile" />
    <!-- 调用隐藏的选择图片标签 -->
<van-cell class="avatar-cell" title="头像" is-link center @click="$refs.imgFile.click()" >
changeFile 方法被调用 :
 changeFile() {
      console.dir(this.$refs.imgFile.files); // filelist对象
      const imgFile = this.$refs.imgFile.files[0]; // 接口需要的参数 file类型的图片
      console.log(imgFile.size);
      if (imgFile.size > 1024 * 1024 * 2)
        return this.$toast.fail("不允许超过 2 M");
      const typeArr = ["image/png", "image/jpeg", "image/git", "image/jpg"];
      if (!typeArr.includes(imgFile.type))
        return this.$toast.fail("只支持jpg,png,jpeg,gif格式");
    },
      console.dir(this.$refs.imgFile.files); // filelist对象 里面包裹图片数据
 console.dir(this.$refs.imgFile.files[0]); // 图片file文件类型 ;

验证:大小是否大于 2 M ,格式是否符合要求:

  console.dir(this.$refs.imgFile.files); // filelist对象
      const imgFile = this.$refs.imgFile.files[0]; // 接口需要的参数 file类型的图片
      console.log(imgFile.size);
      if (imgFile.size > 1024 * 1024 * 2)
        return this.$toast.fail("不允许超过 2 M");
      const typeArr = ["image/png", "image/jpeg", "image/git", "image/jpg"];
      if (!typeArr.includes(imgFile.type))
        return this.$toast.fail("只支持jpg,png,jpeg,gif格式");

 点击显示图片预览:生成一个图片预览地址(临时地址)

URL.createObjectURL可以生成一个和此窗口的document一个生命周期的临时地址 ;

 

 ps:多次选择相同的图片并不会触发 change 事件 , 需要情空控件的值 

 

 

 流程 :点击

 

 选择图片 :

 开始预览:vant 的popup 包裹一个显示预览图片的组件 ;

<template>
  <div>
    <img style="width: 100%" :src="imgLink" alt="" />
  </div>
</template>

<script>
export default {
  name: "UpdatePhoto",
  props: {
    imgLink: {
      type: String,
      required: true,
    },
  },
};
</script>

<style>
</style>

 

ps:此时的imgFile 是否可以参数请求??? 可以的 

开始进行裁剪 使用的是 cropperjs ;

img 必须是 块级元素 ,是最大宽度 ;

封装修改头像的接口 ;

/**
 * 更新头像资料
 * ====》 data {data:文件信息}
 * 请求头类型 multipart/form-data
 * axios 发生请求 如果 data接收的是一个formData实例 会将请求头的类型自动换成multipart/formData-data
 * 所以我不需要在 headers 自己设置请求头类型了
 */
export const updateUserPhotoApi = (data) =>
  request({
    url: "/v1_0/user/photo",
    method: "patch",
    data,
  });
 submit() {
      console.log(111);
      // 1. 完成裁剪效果
      // 裁剪预览效果 const cropper = new Cropper(图片标签节点,配置项目信息) 预览对象
      // 裁剪功能 cropper.getCropperCanveas().toBlob((blob) => {blob 就是裁剪后的文件信息})
      // ===========? cropper.getCroppedCanvas() 得到一个Canvas处理对象,在调用toBlob方法转正文件信息
      this.$toast.loading("正在更新");
      //   async 修饰回调函数(箭头函数)
      this.cropper.getCroppedCanvas().toBlob(async (blob) => {
        console.log("blob是什么", blob);
        // 2. 完成上传更新图片效果
        // 实例化一个formFData对象
        const fd = new FormData();
        fd.append("photo", blob);
        console.log("fd是什么", fd);
        const { data } = await updateUserPhotoApi(fd);
        // loadign 遇到 success 就会停止 loading
        this.$toast.success("更新完成");
        // console.log(data);
        // 成功时候更新视图 关闭弹层
        this.$emit("updatePhoto", data.data.photo);
        this.$emit("close");
      });
    },

 

posted on 2022-10-18 10:31  流浪のwolf  阅读(260)  评论(0编辑  收藏  举报