项目本地上传文件(cropper的用法)
Posted 做个机灵鬼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目本地上传文件(cropper的用法)相关的知识,希望对你有一定的参考价值。
场景: 项目中需要上传本地文件(图片、视频等)
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]);
//展示弹出层
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);
//关闭弹出
this.$emit("close");
//成功提示
this.$toast.success("修改成功");
//更新视图
this.$emit("updataPhoto", data.data.photo);
catch (error)
console.log(error);
this.$toast.faile("身份过期,请尝试重新登录");
,
,
以上是关于项目本地上传文件(cropper的用法)的主要内容,如果未能解决你的问题,请参考以下文章