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

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

最近公司老项目改用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的保持一致。

相关文章
|
11天前
|
Web App开发 资源调度 JavaScript
vue element plus 安装
vue element plus 安装
29 0
|
11天前
|
JavaScript API PHP
vue element plus 快速开始
vue element plus 快速开始
32 0
|
11天前
|
JavaScript 前端开发 数据安全/隐私保护
vue element plus Input 输入框
vue element plus Input 输入框
33 0
|
1天前
|
JavaScript
vue中高精度小数问题(加减乘除方法封装)处理
vue中高精度小数问题(加减乘除方法封装)处理
10 0
|
6天前
|
JavaScript
【vue】 element upload文件上传后表单校验信息还存在
【vue】 element upload文件上传后表单校验信息还存在
14 1
|
7天前
|
JavaScript
Vue 开发技巧·1
【4月更文挑战第2天】通过props解耦Vue组件与路由参数,避免使用`$route`导致的高耦合。在路由配置中设定`props: true`,如`{ path: /user/:id, component: User, props: true }`,使组件能直接通过`props`获取`params`。此外,功能组件是无状态、不可实例化的,依赖外部数据且无生命周期,提高渲染性能。通过上下文参数传递所需数据,如`{{item.title}} {{item.content}}`,在父组件中定义并传递`list`数据。
26 8
|
10天前
|
JavaScript
vue element 导出blob后台文件流xlsx文件自动下载(且规避乱码)
vue element 导出blob后台文件流xlsx文件自动下载(且规避乱码)
|
11天前
|
JavaScript API
vue element plus Button 按钮
vue element plus Button 按钮
30 0
|
11天前
|
JavaScript 容器
vue element plus Space 间距
vue element plus Space 间距
25 0
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
980 0