由於業務需求需要支持多文件上傳, 出於復用思想,就把element的上傳文件組件進行了二次封裝 ,但是多文件上傳的時候發現報錯: Cannot set property 'status' of null
踩坑之路開始, 查了下網上說是 fileList 這個值不能修改, 不明所以, 看了下報錯是沒有獲取file對象, 導致了獲取文件對象身上的狀態報錯,下圖的 file為null, 猜測是因為此時文件未上傳成功, 導致了獲取解析文件得到null
廢話不多說了, 上代碼,
parent component:
<template>
<div class="home">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="圖片上傳">
<uploaderImgs
:imagesList="form.imgs"
@imageUpload="imageUpload"
@imageRemove="imageRemove"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">確定</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
// @ is an alias to /src
import uploaderImgs from "@/components/uploaderImgs.vue";
export default {
name: "Home",
components: {
uploaderImgs
},
data() {
return {
form: {
imgs: [
"https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1913214116,3912663704&fm=26&gp=0.jpg",
]
}
};
},
methods: {
// ---圖片
imageRemove(url) {
this.form.imgs = this.form.imgs.filter(v => v !== url);
},
imageUpload(url) {
this.form.imgs.push(url);
},
// ----
onSubmit() {
console.log(this.form);
}
}
};
</script>
Child components:
<template>
<div class="uploader-imgs">
<el-upload
ref="upload"
:action="action"
:headers="headers"
list-type="picture-card"
:before-upload="beforeAvatarUpload"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
:on-exceed="handleExceed"
:file-list="fileList"
:limit="limit"
:multiple="multiple"
:class="[{heidden:imagesList.length >= limit}]"
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt />
</el-dialog>
</div>
</template>
<script>
export default {
props: {
imagesList: {
type: Array,
default() {
return [];
}
},
limit: {
type: Number,
default: 10
},
multiple: {
type: Boolean,
default: true
},
action: {
required: true,
type: String,
},
headers: {
type: Object,
default() {
return { };
}
}
},
data() {
return {
dialogImageUrl: "",
dialogVisible: false
};
},
computed: {
// 生成回顯文件列表
fileList() {
if (this.imagesList && this.imagesList.length) {
return this.imagesList.map(v => {
let uid = this.createRandomUid();
return { uid, url: v };
});
} else {
return [];
}
}
},
methods: {
// 生成隨機uid
createRandomUid() {
return Math.random()
.toString()
.split(".")[1];
},
// 上傳限制
beforeAvatarUpload(file) {
const isJPG =
file.type === "image/jpeg" ||
file.type === "image/gif" ||
file.type === "image/png" ||
file.type === "image/jpg";
const isSize= file.size / 1024 / 1024 < 10;
if (!isJPG) {
this.$message.error("上傳圖片格式有誤");
}
if (!isSize) {
this.$message.error("上傳頭像圖片大小不能超過 10MB!");
}
return isJPG && isSize;
},
// 圖片移除
handleRemove(file, fileList) {
this.$emit("imageRemove", file.url);
},
// 上傳成功
handleSuccess(res, file, fileList) {
let url = `后台返回來的地址`;
// 延遲觸發 防止多文件上傳報錯 如果是多文件模式 則延遲一秒后改變數據 視文件大小決定延遲時間 不然還是會獲取不到file對象
if (this.multiple) {
setTimeout(() => {
this.$emit("imageUpload", url);
}, 1000);
} else {
this.$emit("imageUpload", url);
}
},
// 圖片預覽
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
// 超過數量
handleExceed() {
this.$message.error("超過最大上傳數量,請重新選擇");
}
}
};
</script>
<style lang="scss">
.uploader-imgs {
.el-upload-list__item {
transition: none !important;
}
.heidden {
.el-upload--picture-card {
display: none;
}
}
}
</style>