在vue项目中封装上传图片功能js文件,支持自定义页面样式图片上传,支持多图上传及控制大小等

项目中上传图片功能用到的很多,且每个页面上传样式不统一,所以封装一个图片上传JS文件,包含多图上传

最近开发的项目,因为上传图片功能在页面中用到的地方特别多,而且每个页面上传的样式还不统一,所以不能以组件形式封装,考虑了下,能不能将上传文件功能封装成个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,支持旋转、缩放、翻转等操作,还是很简单的,需要的可以去看看

Vue图片浏览组件v-viewe

之所以传入_self,还是因为在封装的js文件中方法互相调会出现问题。
该上传只支持ie10以及10以上,其它浏览器没问题。。。
好不容易封装完,可惜最后老大说又要兼容ie9…

好吧,这个留存,再封一套支持vue ie9图片上传预览的组件。下一篇见,有疑问及需要的留言。


版权声明:本文为weixin_42826247原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。