@15013890200
2018-08-29T09:33:28.000000Z
字数 4927
阅读 780
vue javascript 插件
文件上传功能是交互式网站必不可少的功能。一年前,笔者还是什么都不懂得小白(虽然现在懂得也很少)的时候,被这个功能折磨了好一阵子。求助师兄师姐才勉强会用封装好的插件。
最近,抽空写了个简单的文件上传插件,下面将介绍此插件的特点。1、该插件严格上来说,并不能算真正的文件上传插件。我只是利用该插件获取到自己选择的文件的信息,包括文件对象和文件base64编码,然后返回。至于后来怎样上传、何时上传就因人而异。
2、该插件支持的配置:是否支持多选、上传文件的大致类型、上传文件的后缀、上传文件的字节大小、上传文件的宽高、是否严格限制上传文件的宽高。
3、由于该插件并不将文件直接上传到服务器。因此给用户带来撤回选择文件的功能,减轻服务器的压力。
4、选择的文件展示方面,支持图片缩略图。定制化excel、word、ppt、txt、html、pdf、rar、video文件图标,以及默认文件图标。
源代码
<template><div class="j_div_upload clearfix"><input type="file" class="j_ip_hide" @change="getSelect"><div class="j_div_imgs"><div class="j_imgs_div"><div v-for="(img,index) in imgs" class="j_div_item"><img :src="img.icon?img.icon:img.base64" class="j_img_item"><span :title="img.name">{{img.name}}</span><i class="j_i_close" @click="deleteItem(index)"></i></div></div><div class="j_div_add" @click="select"></div></div></div></template><script>import Vue from 'vue';export default{name: 'myupload',data(){return {imgs: [],//存放选中的文件对象multiple: false,//标志是否支持多文件上传type: '',//文件的大致类型。目前最好传入image或者videosize: null,//允许文件的字节大小format: [],//允许文件的具体后缀width: null,//图片的宽度height: null,//图片的高度strict: false,//图片长宽是否严格限制在标注尺寸icon: require('./img/file.png')}},props: {uploadObj: {type: Object,default: null}},methods: {select: function(){/** 触发文件上传操作 */this.$el.firstChild.click();},getSelect: function(event){/** 获取文件对象并进行处理和控制 */if(!event.target.files || !event.target.files[0])return;let _this = this;let file = event.target.files[0];if(this.type && file.type.indexOf(this.type) === -1){this.Layer.alert('上传文件类型错误,应该上传 '+this.type+' 类型');return;}if(this.format && this.format.length){let file_type = file.name.split('.').pop(1).toLowerCase();if(this.format.indexOf(file_type) === -1){this.Layer.alert('上传文件后缀与指定后缀类型不符( '+this.format.join(',')+' )');return;}}if(this.size && file.size > this.size * 1024 * 1024){this.Layer.alert('文件超过'+this.size+'M限制');return;}let reader = new FileReader();reader.readAsDataURL(file);reader.onload = function(evt){if(file.type.indexOf('image') !== -1){let image = new Image();image.src = evt.target.result;image.onload = function(){let w = image.width;let h = image.height;if(_this.strict){if(_this.width && _this.height && (w != _this.width || h != _this.height)){_this.Layer.alert('图片的宽高不符合要求,宽必须为:'+_this.width+',高必须为:'+_this.height);return;}}else{if(_this.width && _this.height && (w > _this.width || h > _this.height)){_this.Layer.alert('图片的宽高不符合要求,宽不能大于:'+_this.width+',高不能大于:'+_this.height);return;}}if(_this.multiple){_this.imgs.push({name: file.name,date: file.lastModified,base64: evt.target.result,file: file});}else{_this.imgs = [{name: file.name,date: file.lastModified,base64: evt.target.result,file: file}];}}}else{let file_tail = file.type.split('.').pop();switch(file_tail){case 'sheet': _this.icon = require('./img/excel.png');break;case 'document': _this.icon = require('./img/word.png');break;case 'presentation': _this.icon = require('./img/ppt.png');break;default: _this.icon = require('./img/file.png');}if(file.type.indexOf('pdf') !== -1)_this.icon = require('./img/pdf.png');if(file.type.indexOf('video') !== -1)_this.icon = require('./img/video.png');if(file.type === 'text/plain')_this.icon = require('./img/txt.png');if(file.type === 'text/html')_this.icon = require('./img/html.png');if(!file.type && file.name.split('.').pop() == 'rar')_this.icon = require('./img/rar.png');if(_this.multiple){_this.imgs.push({name: file.name,date: file.lastModified,base64: evt.target.result,file: file,icon: _this.icon});}else{_this.imgs = [{name: file.name,date: file.lastModified,base64: evt.target.result,file: file,icon: _this.icon}];}}}setTimeout(function(){event.target.files = null;},500);},deleteItem: function(idx){/** 删除已选的文件 */this.imgs.splice(idx,1);}},beforeMount(){for(let i in this.uploadObj){if(i !== 'imgs'){this.$data[i] = this.uploadObj[i];}}console.log(this.uploadObj);},watch: {'imgs': function(){let files = {base64: [],files: []};this.imgs.forEach(function(item){files.base64.push(item.base64);files.files.push(item.file);});this.$emit('callback',files);}}}</script><style scoped>*{padding: 0;margin: 0;}.j_div_upload{margin-bottom:10px;}.j_ip_hide{width: 0;height: 0;opacity: 0;overflow: hidden;border:none;outline: none;margin: 0;padding: 0;}.j_div_add{width: 80px;height: 80px;background:url(img/add-pic.png) no-repeat;background-size: 80px 80px;margin: 0;float: left;cursor: pointer;}.j_imgs_div,.j_div_imgs{float:left;}.j_div_item{width:80px;height:100px;float:left;margin-right:10px;text-align:center;position:relative;}.j_img_item{width:80px;height:80px;background-color:#ddd;}.j_div_item span{color:#bbb;font-size:12px;float:left;display:inline-block;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.j_i_close{background:url(img/close.png) no-repeat;display:inline-block;width:16px;height:16px;position:absolute;top:-5px;right:-5px;cursor:pointer;}</style>
插件注册及引用省略
参数配置
| 参数名 | 参数意义 | 参数类型 | 默认值 | 是否必须 |
|---|---|---|---|---|
| multiple | 是否支持多文件上传 | Boolean | false | 否 |
| type | 支持文件大致格式(最好传image或video) | string | 无 | 否 |
| size | 支持文件字节大小 | number | null | 否 |
| format | 允许的文件后缀 | array | null | 否 |
| width | 图片的宽度限制 | number | null | 否 |
| height | 图片的高度限制 | number | null | 否 |
| strict | 是否严格限制图片宽高 | Boolean | false | 否 |
当strict参数为true时,会严格限制图片的宽高等于约定的尺寸,否则只控制图片的宽高小于约定的尺寸即可。
效果图



