最近开发的项目,因为上传图片功能在页面中用到的地方特别多,而且每个页面上传的样式还不统一,所以不能以组件形式封装,考虑了下,能不能将上传文件功能封装成个JS文件,在使用的地方调用。这样页面样式展示既可以多样化,又能完美使用功能。开动…
1.举例子
页面中很多类似上传图片的功能,只截图两个。采用base64上传
2.封装一个js文件,采用的是vue插件封装方法exports.install(如果不这样封装,JS文件的this无法指向VUE实例)代码如下:
exports.install = function (Vue) {
Vue.prototype.fileClick = () => {
document.getElementById('upload_file').click()
};
Vue.prototype.fileChange = (el,_self) => {
console.log(el);
// 为input框设置图片路径
_self.imageName = document.getElementById("upload_file").value
if (!el.target.files[0].size) return;
_self.fileList(el.target,_self);
el.target.value = ''
};
Vue.prototype.fileList = (fileListArr,_self) => {
let files = fileListArr.files;
// console.log(fileList);
console.log(1);
for (let i = 0; i < files.length; i++) {
//判断是否为文件夹
if (files[i].type != '') {
// console.log(2);
console.log(files[i]);
_self.fileAdd(files[i],_self);
} else {
//文件夹处理
console.log(1);
_self.folders(fileList.items[i],_self);
}
}
};
//文件夹处理
Vue.prototype.folders = (files,_self) => {
//判断是否为原生file
if (files.kind) {
files = files.webkitGetAsEntry();
}
files.createReader().readEntries(function (file) {
for (let i = 0; i < file.length; i++) {
if (file[i].isFile) {
_self.foldersAdd(file[i],_self);
} else {
_self.folders(file[i],_self);
}
}
})
};
Vue.prototype.foldersAdd = (entry,_self) => {
entry.file(function (file) {
_self.fileAdd(file)
})
};
Vue.prototype.fileAdd = (file,_self) => {
// 判断还可以上传几张图片,多图上传时使用
_self.limitStill ? _self.limitStill-- : _self.limitStill
//判断是否为图片文件
if (file.type.indexOf('image') == -1) {
file.src = 'wenjian.png';
_self.imgList.push({
file
});
} else {
let reader = new FileReader();
let image = new Image();
reader.readAsDataURL(file);
reader.onload = function () {
file.src = this.result;
image.onload = function () {
let width = image.width;
let height = image.height;
file.width = width;
file.height = height;
// 判断是多张上传还是单张上传
if (_self.limitNum <= 1) {
// 单张上传
//总大小
_self.imageSize = file.size;
_self.imgList = [{ file }]
} else {
// 多图上传
//总大小
_self.imageSize = _self.imageSize + file.size;
console.log(_self.imageSize);
_self.imgList.push({
file
})
}
console.log(_self.imgList);
};
// console.log(file.src);
image.src = file.src;
}
}
};
Vue.prototype.fileDel = (index,_self) => {
// 清空图片路径
_self.imageName = ''
_self.imageSize = _self.imageSize - _self.imgList[index].file.size;//总大小
console.log(_self.imageSize);
_self.imgList.splice(index, 1);
// if (_self.limitStill !== undefined) _self.limitStill = _self.imgList.length;
};
Vue.prototype.bytesToSize = (bytes) => {
if (bytes === 0) return '0 B';
let k = 1000, // or 1024
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
}
2.在main.js中引入插件并使用(这里面比较坑的是JS中用的上传图片input及imgID名字是固定的,且用原生JS操作了dom)
import upImage from '@/components/upImage/upImage.js'
Vue.use(upImage)
3.在使用页面引入
这是上传图片中在未上传前默认的图片样式(如下图),需要的同学可以自己换成自己的
4.页面中自定义样式全部使用class自己控制。
<input @change="fileChange_image($event)" type="file" id="upload_file" style="display: none" />
<Input :value="imageName" disabled class="input_weigth_f" /><Button type="primary" @click="fileClick_image">选择</Button>
因原input框在各页面展示不一样,需要我们用现在ui组件新建一个调用它。
这是本人的css样式。
.upload_warp_img_div_del {
position: absolute;
top: 6px;
right: 4px;
width: 16px;
}
.upload_warp_img_div_top {
position: absolute;
top: 0;
width: 100%;
height: 30px;
background-color: rgba(0, 0, 0, 0.4);
line-height: 30px;
text-align: left;
color: #fff;
font-size: 12px;
text-indent: 4px;
}
.upload_warp_img_div_text {
white-space: nowrap;
width: 80%;
overflow: hidden;
text-overflow: ellipsis;
}
.imageContent {
width: 100%;
height: 100%;
vertical-align: middle;
}
.imageContent1{
width: 40px;
height: 40px;
margin-top: 38px;
}
.upload_warp_img_div {
position: relative;
height: 120px;
width: 100px;
border: 1px solid #ccc;
float: left;
line-height: 100px;
display: table-cell;
text-align: center;
background-color: #eee;
cursor: pointer;
}
需要注意的是:方法名、标签的id及上图的imgList、imageSize、limitStill、limitNum、imageName都不可边,如果变需要去JS文件中对应更改调。
5.在methods内声明input的点击方法调用
// 删除图片函数
fileDelCurrent (index) {
var _self = this
this.fileDel(index, _self)
},
// 点击按钮选择图片函数
fileClick_image () {
this.fileClick()
},
// 触发图片改变函数方法
fileChange_image (el) {
var _self = this
this.fileChange(el, _self)
},
图片预览使用的是Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作,还是很简单的,需要的可以去看看
之所以传入_self,还是因为在封装的js文件中方法互相调会出现问题。
该上传只支持ie10以及10以上,其它浏览器没问题。。。
好不容易封装完,可惜最后老大说又要兼容ie9…
好吧,这个留存,再封一套支持vue ie9图片上传预览的组件。下一篇见,有疑问及需要的留言。
版权声明:本文为weixin_42826247原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。