项目本地上传文件

项目本地上传文件,第1张

场景: 项目中需要上传本地文件(图片、视频等)
html提供了input标签可以上传文件
< input type="file" />
//这样页面中就会生成按钮,点击可以上传文件
//但是一般不这样使用,因为原生的按钮不美观

给input标签添加hideen属性,那么input标签就会隐藏起来

 <input type="file" hidden ref="file" @change="onFileChange" />

change事件,在选择本地文件并且确认的时候就会触发,但他不是每次都会触发,如果两次选择的文件是同一个时,那么第二次就不会触发,下面讲解解决的方法

有这样一个场景,点击更换头像,那么就可以通过点击更换头像的按钮来触发已经隐藏的input框

 //点击头像
    onChangePhoto() {
      //因为input框已经隐藏了,通过点击其他的框来触发原来的input的的点击事件
      this.$refs.file.click();
    },

当选择好本地的文件按确认时就会触发input的change事件

 //@change这个事件什么时候触发?pc端为例: 在选择了电脑文件并点击确认后触发
    onFileChange() {
      /*
      this.$refs.file.files[0] 
      获取到的是一个复杂对象,里面包含图片的大小,图片的类型,当前的时间
       console.log(1111, this.$refs.file.files[0]);
      */
      /* 
      进过window.URL.createObjectURL会获得一个http格式的url路径
     */
      this.img = window.URL.createObjectURL(this.$refs.file.files[0]);

      //展示d出层
      this.userPhotoShow = true;
      //当第二次选择同一个文件时,@change函数就会不被触发,我们可以令this.$refs.file的value等于空
      this.$refs.file.value = "";
    },
   
    

在 Gecko 1.9.2 之前,通过 input 元素,每次只能选择一个文件,这意味着该 input 元素的 files 属性上的 FileList 对象无论如何都只能包含一个文件。从Gecko 1.9.2 开始,如果一个 input 元素拥有 multiple 属性,则可以用它来选择多个文件。当选择多个文件时,返回的就是fileList一个数组

<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<!-- multiple 属性允许用户选择多个文件 -->

<input id="myfiles" multiple type="file">

</body>

<script>

var pullfiles=function(){
    // love the query selector
    var fileInput = document.querySelector("#myfiles");
    var files = fileInput.files;
    // 获取所选文件数量
    var fl = files.length;
    var i = 0;

    while ( i < fl) {
        // localize file var in the loop
        var file = files[i];
        alert(file.name);
        i++;
    }
}

// 设置 change 事件处理函数
document.querySelector("#myfiles").onchange=pullfiles;

</script>

</html>
图片上传的例子

既然上传图片那么肯定会涉及到图片裁剪,需要用到第三方库cropperjs ,具体使用方法参考官方文档
首先

npm install cropperjs

设置存照片的盒子

img {
  display: block;

  /* This rule is very important, please don't ignore this */
  max-width: 100%;
}

在对应的组件引入corpper以及它的样式

import "cropperjs/dist/cropper.css";
import Cropper from "cropperjs";
头像裁剪

在mounted函数中设置裁剪框的样式

mounted() {
    //获取到dom元素节点,
    const image = this.$refs.img;
    //cropper为data中的数据 初始化为null,newcropper返回的是cropper对象,一个复杂对象
    this.cropper = new Cropper(image, {
      viewMode: 1, //试图模式,剪切框架不可以超出图片
      dragMode: "move", //移动模式,move可以移动图片
      aspectRatio: 1, //固定裁剪框的比例,一般是正方形,选用1/1 ,简写1
      autoCropArea: 1, //自定义裁剪区的大小,它应该是一个介于 0 和 1 之间的数字。定义自动裁剪区域大小(百分比)
      cropBoxMovable: false, //启用此选项可通过拖动来移动裁剪框。
      cropBoxResizable: false, //启用可以缩放裁剪框的大小
      background: false, //不启用默认的背景
    });
  },
保存更新

在裁剪完成之后,就把发送请求,把图片发送到服务器

如果 Content-Type 要求是 application/json ,则 data 传普通对象 {}
如果 Content-Type 要求是 multipart/form-data ,则 data 传 FormData 对象
纵观所有数据接口,你会发现大多数的接口都要求 Content-Type 要求是 application/json
一般只有涉及到文件上传的数据接口才要求Content-Type 要求是 multipart/form-data
这个时候传递一个 FormData 对象

如果是基于服务端的裁切,则使用:getData 方法,该方法得到裁切的区域参数。需要后端接口配合

如果是纯客户端的图片裁切,则使用:getCroppedCanvas 方法,该方法得到裁切之后的图片对象(类似于URL.createObjectURL 方法得到的文件对象)。

 methods: {
    confirm() {
   
      // 这个时候传递一个 FormData 对象
   
      //纯客户端裁切文件,利用getCroppedCanvas()获取裁切的文件对象
      this.cropper.getCroppedCanvas().toBlob((blob) => {
        const formData = new FormData();
        //向 FormData 中添加新的属性值,FormData 对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。
        formData.append("photo", blob);
        this.updataPhoto(formData);
      });
    },
    
    async updataPhoto(formData) {
      this.$toast.loading({
        duration: 0, // 持续展示 toast
        forbidClick: true,
        message: "加载中",
      });
      try {
        const { data } = await updataUserPhoto(formData);
        //关闭d出
        this.$emit("close");
        //成功提示
        this.$toast.success("修改成功");
        //更新视图
        this.$emit("updataPhoto", data.data.photo);
      } catch (error) {
        console.log(error);
        this.$toast.faile("身份过期,请尝试重新登录");
      }
    },
  },

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/939722.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存