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的保持一致。

相关文章
|
3天前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
49 1
|
3月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
515 0
|
3月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
2月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
94 0
|
2月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
219 1
|
存储 JavaScript 网络架构
Vue3新增功能特性
Vue3相比Vue2更新技术点
|
5月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
725 4
|
4月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
523 77
|
5月前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
3月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
355 17