图片上传:
<template> <div class="upload-pic"> <el-upload class="upload-demo" :action="uploadFdfsFileUrl" :headers="requestHeader" list-type="picture-card" name="file" :before-upload="beforeAvatarUpload" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-remove="beforeRemove" :on-success="handleSuccess" :on-error="handleError" :multiple="multiple" :limit="limitNum" :on-exceed="handleExceed" :file-list.sync="picWebUrlList" > <i class="el-icon-plus"></i> </el-upload> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt=""> </el-dialog> </div> </template>
import { mapGetters, mapActions } from 'vuex' import { getToken } from '@/utils/auth' export default { name: 'UploadPic', props: { isEdit: { type: Boolean, default: false }, // 是否多选 multiple: { type: Boolean, default: true }, // 文件列表 fileList: { type: Array, default: () => [] }, // 限制上传个数 limitNum: { type: Number, default: null } }, data() { return { // 附件上传请求头 requestHeader: '', // 图片上传路径 picUploadList: [], // 图片回显路径 picWebUrlList: [], // 预览路径 dialogImageUrl: '', // 预览弹框 dialogVisible: false, // 删除图片下标 delIndex: null } }, computed: { ...mapGetters([ 'uploadFdfsFileUrl' ]) }, watch: {}, /** * 生命周期函数--el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子 */ mounted: function() {}, created() { // 设置文件按上传请求头 this.requestHeader = { 'Authorization': 'Bearer ' + getToken('token') } }, methods: { ...mapActions([ 'download' ]), refreshPicData(value) { this.picUploadList = value this.getWebUrlList() }, // 图片回显数组 getWebUrlList() { let webUrlList = [] if (this.picUploadList.length > 0) { this.picUploadList.forEach((item, index) => { // 获取图片 web 地址 this.$store.dispatch('dictionary/getWebFileUrl', item.url).then(response => { const fileObj = { index: index, name: '', url: response.data } webUrlList.push(fileObj) }) }) this.picWebUrlList = webUrlList } }, // 图片格式及大小限制 beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpg' const isJPEG = file.type === 'image/jpeg' const isGIF = file.type === 'image/gif' const isPNG = file.type === 'image/png' const isBMP = file.type === 'image/bmp' const isLt2M = file.size / 1024 / 1024 < 2 if (!isJPG && !isJPEG && !isGIF && !isPNG && !isBMP) { this.$message.error('上传图片必须是JPG/JPEG/GIF/PNG/BMP 格式!') } if (!isLt2M) { this.$message.error('上传图片大小不能超过 2MB!') } return (isJPG || isJPEG || isBMP || isGIF || isPNG) && isLt2M }, // 点击预览图标,预览图片 handlePictureCardPreview(file) { this.dialogImageUrl = file.url this.dialogVisible = true }, // 文件列表移除文件时的钩子 handleRemove(file, fileList) { if (this.isEdit) { this.picUploadList.splice(this.delIndex, 1) this.$emit('update:fileList', this.picUploadList) } else { const fileArr = [] fileList.forEach(item => { if (item.response) { const fileObj = { name: item.name, url: item.response.data } fileArr.push(fileObj) } else { fileArr.push(item) } }) this.$emit('update:fileList', fileArr) } }, // 删除文件之前的钩子 beforeRemove(file, fileList) { fileList.forEach((item, index) => { if (file.url === item.url) { this.delIndex = index } }) return this.$confirm('', `确定移除 ${file.name}?`, { customClass: 'del-dialog' }) }, // 文件上传成功时的钩子 handleSuccess(response, file, fileList) { if (response.code === '1') { if (this.isEdit) { const fileObj = { index: this.picUploadList.length, name: file.name, url: response.data } this.picUploadList.push(fileObj) this.$emit('update:fileList', this.picUploadList) } else { const fileArr = [] fileList.forEach(item => { if (item.response) { const fileObj = { name: item.name, url: item.response.data } fileArr.push(fileObj) } else { fileArr.push(item) } }) this.$emit('update:fileList', fileArr) } } else { this.$message({ message: `${file.name} 上传失败,请重新再试`, type: 'error', duration: 2000 }) } }, // 文件上传失败时的钩子 handleError(err, file, fileList) { console.log(err) this.$message({ message: `${file.name} 上传失败,请重新再试`, type: 'error', duration: 2000 }) }, // 文件超出个数限制时的钩子 handleExceed(files, fileList) { this.$message.warning(`当前限制选择 ${this.limitNum} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`) } } }
父组件引用:<upload-pic ref="refreshData" :file-list.sync="formData.picList" :limit="1" :is-edit="isEdit"></upload-pic>
在编辑图片时,将编辑图片的数组传递给图片上传组件,否则不能回显父组件拿到图片数据后,通过调用图片上传组件内的 refreshPicData 方法,传递图片数据。
文件上传:
<template> <div class="upload-file"> <el-upload class="upload-demo" :action="uploadFdfsFileUrl" :headers="requestHeader" name="file" :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" :on-success="handleSuccess" :on-error="handleError" :multiple="multiple" :limit="limitNum" :on-exceed="handleExceed" :file-list.sync="fileList" > <el-button class="dashed-btn" icon="el-icon-upload" size="small">{{ btnTxt }}</el-button> <div slot="tip" class="el-upload__tip">{{ tipTxt }}</div> </el-upload> </div> </template>
import { mapGetters, mapActions } from 'vuex' import { getToken } from '@/utils/auth' export default { name: 'UploadFile', props: { // 是否多选 multiple: { type: Boolean, default: true }, // 文件列表 fileList: { type: Array, default: () => [] }, // 限制上传个数 limitNum: { type: Number, default: null }, // 按钮文字 btnTxt: { type: String, default: '上传附件' }, // tip 提示 tipTxt: { type: String, default: '' } }, data() { return { // 附件上传请求头 requestHeader: '' // 限制文件数量 // limitNum: '' // 文件列表 // fileList: [] } }, computed: { ...mapGetters([ 'uploadFdfsFileUrl' ]) }, watch: {}, /** * 生命周期函数--el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子 */ mounted: function() {}, created() { // 设置文件按上传请求头 this.requestHeader = { 'Authorization': 'Bearer ' + getToken('token') } }, methods: { ...mapActions([ 'download' ]), // 点击文件列表中已上传的文件时的钩子,下载文件 handlePreview(file) { console.log(file) // const param = { // fileUrl: file.url // } // this.$store.dispatch('dictionary/downLoad', param).then(response => { // console.log(response) // let fileName = localStorage.fileName // fileName = decodeURI(fileName.substr(fileName.indexOf('=') + 1)) // const paramData = { // data: response, // title: '天津园区电梯监控.xlsx' // } // this.download(paramData) // }) }, // 文件列表移除文件时的钩子 handleRemove(file, fileList) { const fileArr = [] fileList.forEach(item => { if (item.response) { const fileObj = { name: item.name, url: item.response.data } fileArr.push(fileObj) } else { fileArr.push(item) } }) this.$emit('update:fileList', fileArr) }, // 删除文件之前的钩子 beforeRemove(file, fileList) { return this.$confirm('', `确定移除 ${file.name}?`, { customClass: 'del-dialog' }) }, // 文件上传成功时的钩子 handleSuccess(response, file, fileList) { if (response.code === '1') { const fileArr = [] fileList.forEach(item => { if (item.response) { const fileObj = { name: item.name, url: item.response.data } fileArr.push(fileObj) } else { fileArr.push(item) } }) this.$emit('update:fileList', fileArr) } else { this.$message({ message: `${file.name} 上传失败,请重新再试`, type: 'error', duration: 2000 }) } }, // 文件上传失败时的钩子 handleError(err, file, fileList) { console.log(err) this.$message({ message: `${file.name} 上传失败,请重新再试`, type: 'error', duration: 2000 }) }, // 文件超出个数限制时的钩子 handleExceed(files, fileList) { this.$message.warning(`当前限制选择 ${this.limitNum} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`) } } }
父组件引用:<upload-file :file-list.sync="formData.fileList" ></upload-file>