vue开发:对Element上传功能的二次封装

最近公司老项目改用vue开发,前端框架采用element ui,这个框架风格还是很漂亮的,只是上传功能有一些问题,比如:limit=1限制上传数量后,后面的添加按钮没有隐藏,再用就是如果上传图片组,很多需求需要对图片组进行排序修改,基于这两个需求,对element的el-upload组件进行了二次封装。

首先引入sortable.js这个插件,这个是一个很强大的排序插件,下面直接上我封装的上传代码

组件的html部分:

<template id='example'>
 <div>
 <el-upload :action="elAction"
 :ext="elExt"
 :data="elData"
 :file-list="elFileList"
 :limit="elLimit"
 :on-exceed="onElExceed"
 :before-upload="beforeElUpload"
 :on-remove="onElRemove"
 :before-remove="beforeElRemove"
 :on-success="onElSuccess"
 :on-error="onElError"
 :on-change="onElChange"
 :list-type="elListType"
 :on-preview="pictureCardPreview"
 :class="{elExceed:checkLimit}">
 <i class="el-icon-plus" v-if="isImage"></i>
 <el-button size="small" type="primary" v-else>点击上传</el-button>
 </el-upload>
 <el-dialog :visible.sync="dialogVisible" size="tiny" v-if="isImage">
 <img width="100%" :src="dialogImageUrl" alt="">
 </el-dialog>
 </div>
</template>

组件的注册js

 Vue.component('pa-upload', {
 template: '#example',
 props: {
 data: Object,
 limit: {
 type:Number,
 default:0
 },
 fileList: Array,
 ext: {
 type: String,
 default: ".jpg,.png,.gif"
 },
 maxSize: {
 type: Number,
 default: 1204
 },
 action:String,
 listType: {
 type: String,
 default: "picture-card"
 },
 sortable: { type: Boolean, default: false },
 onPreview: { type: Function, default: function () { } },
 onRemove: { type: Function, default: function () { } },
 onSuccess: { type: Function, default: function () { } },
 onError: { type: Function, default: function () { } },
 onProgress: { type: Function, default: function () { } },
 onChange: { type: Function, default: function () { } },
 beforeUpload: { type: Function, default: function () { return true;}},
 beforeRemove: { type: Function, default: function () { return true;}},
 },
 data: function(){
 return {
 dialogImageUrl: "",
 dialogVisible: false,
 elAction: this.action,
 elSortable: this.sortable,
 elCount:0,
 elData:this.data,
 elFileList: this.fileList,
 elLimit: this.limit,
 elExt: this.ext,
 elMaxSize: this.maxSize,
 elListType: this.listType,
 }
 },
 created: function ()
 {
 this.elCount = this.elFileList.length;
 },
 mounted: function () {
 var that = this;
 if (this.elSortable)
 {
 var list = this.$el.querySelector('.el-upload-list');
 new Sortable(list, {
 onEnd: function (ev) {
 var arr = that.elFileList;
 arr[ev.oldIndex] = arr.splice(ev.newIndex, 1, arr[ev.oldIndex])[0];
 },
 });
 }
 },
 computed: {
 checkLimit: function () {
 //console.log(this.elLimit > 0 && this.elCount >= this.elLimit)
 return (this.elLimit > 0 && this.elCount >= this.elLimit)
 },
 isImage: function () {
 return this.elListType == "picture-card";
 },
 },
 watch: {
 elFileList: {
 handler(newName, oldName) {
 //console.log(this.elFileList);
 this.$emit('input', JSON.stringify(newName));//传值给父组件, 让父组件监听到这个变化
 },
 immediate:true // 代表在wacth里声明了firstName这个属性之后立即先去执行handler方法
 }
 },
 methods: {
 beforeElUpload: function (file)
 {
 console.log("beforeUpload");
 var ext = this.elExt;
 var maxSize = this.elMaxSize;
 var isOkExt = ext.indexOf(file.name.substring(file.name.lastIndexOf('.'))) >= 0;
 if (!isOkExt) {
 this.$message.error('只能上传' + ext + '格式的文件');
 return false;
 }
 var isLtmaxWidth = file.size / 1024 < maxSize;
 if (!isLtmaxWidth) {
 this.$message.error('上传文件大小不能超过' + maxSize + 'KB!');
 return false;
 }
 return this.beforeUpload(file);
 },
 onElSuccess: function (response, file, fileList)
 {
 this.elCount = fileList.length;
 response.name = file.name;
 response.url = file.url;
 this.elFileList.push(response);
 this.onSuccess(response, file, fileList);
 },
 onElError: function (err, file, fileList) {
 this.onError(err, file, fileList);
 },
 onElChange: function (file, fileList) {
 this.onChange(file, fileList);
 },
 onElProgress: function (event, file, fileList)
 {
 this.onProgress(event, file, fileList);
 },
 onElRemove:function(file, fileList)
 {
 this.elCount = fileList.length;
 this.elFileList = fileList;
 this.onRemove(file, fileList);
 },
 beforeElRemove: function (file, fileList)
 {
 return this.beforeRemove(file, fileList);
 },
 onElExceed: function (files, fileList)
 {
 this.$message.error('只能上传' + this.elLimit + '个文件!');
 },
 pictureCardPreview:function(file) {
 this.dialogImageUrl = file.url;
 this.dialogVisible = true;
 }
 }
 })

组件的使用:

 <pa-upload action="/e/upload/"
 :data="{}"
 :file-list="[{id:1,name:'1.jpg',url:'/upload/test.png'}]"
 ext=".jpg,.png,.docx"
 :max-size="1024"
 :sortable="true"
 list-type="picture-card"
 v-model="image"
 :limit="5">
 </pa-upload>

ext:允许上传的格式

max-size:最大上传尺寸,单位kb

sortable:是否允许拖动排序

v-model:和data中的属性绑定,实现双向绑定。

其他属性和element的保持一致。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券