最近客户写的一个 案子, 需要一个前端比较复杂的步奏型下单功能,然后就稍微看了下 VUE,拿来用了
不得不说,VUE 对于后端工程师还是很友好的,用 api和更多以往后端语言的特性(可能是我不太熟js)来操作前端,这里记录一个 vue + 图片上传
<div class="form-group" id="vue">
<label for="exampleInputPassword1">原始CAD图纸-上传进度({{imgTempList.length}}/5)</label>
<div>
<div class="uploading-data" v-if="isUploading"></div>
<div class="upload-img-column">
<div class="upload-wrap">
<div class="box">
<label class="p dotted">
<input type="file" accept="image/jpg,image/jpeg,image/png" name="file" @change="onChooseImage($event)" />
<img src="images/jiahao.png" alt="">
</label>
</div>
<template v-for="(imgItem, imgIndex) in imgTempList">
<div class="box">
<div class="p">
<img :src="imgItem">
<div class="delete" @click.stop="deleteImg(imgIndex)">
<img src="images/guanbi.png" alt="">
</div>
</div>
</div>
</template>
</div>
</div>
<div class="success-path">
<template v-for="(item, index) in successPath">
<a :href="base+item" target="_blank">{{item}}</a>
</template>
</div>
</div>
<div class="invalid-feedback" v-show="errors.file">
{{errors.file?errors.file[0]:''}}
</div>
</div>
var v1 = new Vue({
el: '#vue',
data: {
imgTempList: [], //图片临时路径列表
isUploading: false, //是否正在上传
successPath: [], //上传成功后的路径(没必要)
base:'/uploads/',
},
methods: {
//选择图片
onChooseImage: function (event) {
var that = this;
//判断图片数量是否已上限
var currentImgTempArray = that.imgTempList;
if (currentImgTempArray.length >= 5) {
alert("最多上传5张图片");
return false;
}
//使用FileReader对文件对象进行操作
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]); //将读取到的文件编码成Data URL
reader.onload = function () { //读取完成时
var replaceSrc = reader.result; //文件输出的内容
//调用图片压缩处理方法
that.compressedImage({
src: replaceSrc,
quality: 0.8,
success: function (src) {
//将压缩后的路径 追加到临时路径数组中
var totalList = [];
if (currentImgTempArray.length > 0) {
totalList = currentImgTempArray.concat(src);
} else {
totalList[0] = src;
}
that.imgTempList = totalList;
that.onUploadImg(src)
}
});
};
},
//删除某张图片
deleteImg: function (idx) {
var that = this;
that.imgTempList.splice(idx, 1);
},
//提交上传图片
onUploadImg: function (src) {
var that = this;
that.isUploading = true; //正在上传 显示遮罩层 防止连续点击
var files = that.dataURLtoFile(src, 'pj' + Date.now() + '.jpg'); //DataURL转File
//创FormData对象
var formdata = new FormData();
//append(key,value)在数据末尾追加数据。 这儿的key值需要和后台定义保持一致
formdata.append('img', files);
//用axios上传,
axios({
method: "POST",
//图片上传接口,返回图片存储地址
url: "/api/upload_image/upload",
data: formdata,
headers: {
"Content-Type": "multipart/form-data"
}
}).then(function (res) {
console.log(res.data)
that.isUploading = false;
that.successPath.push(res.data);
console.log(that.successPath)
}).catch(function (error) {
console.error(error);
});
},
/**
* 压缩图片处理
* @src 需要压缩的图片base64路径
* @quality 图片质量 0-1,默认1
* @success() 成功后的回调
* */
compressedImage: function (params) {
var that = this;
var initParams = {
src: params.src || "",
quality: params.quality || 1,
};
var image = new Image();
image.src = initParams.src;
image.onload = function () {
//获取图片初始宽高
var width = image.width;
var height = image.height;
//判断图片宽度,再按比例设置宽度和高度的值
if (width > 1920) {
width = 1920;
height = Math.ceil(1920 * (image.height / image.width));
}
//将图片重新画入canvas中
var canvas = document.getElementById("compressCanvas");
if(!canvas){ //如果没有压缩用的canvas 就创建一个canvas画布
var body = document.body;
canvas = document.createElement("canvas"); //创建canvas标签
canvas.id = "compressCanvas"; //给外层容器添加一个id
canvas.style.position = "fixed";
canvas.style.zIndex = "-1";
canvas.style.opacity = "0";
canvas.style.top = "-100%";
canvas.style.left = "-100%";
body.append(canvas);
}
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
context.beginPath();
context.fillStyle = "#ffffff";
context.fillRect(0, 0, width, height);
context.fill();
context.closePath();
context.drawImage(image, 0, 0, width, height);
var replaceSrc = canvas.toDataURL("image/jpeg", initParams.quality); //canvas转DataURL(base64格式)
params.success && params.success(replaceSrc);
};
},
/**
* 将base64转换为文件
* @dataUrl base64路径地址
* @fileName 自定义文件名字
* */
dataURLtoFile: function (dataUrl, fileName) {
var 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});
},
}
})