vue開發:對Element上傳功能的二次封裝

原文鏈接:https://yq.aliyun.com/articles/713943

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章