<template>
<div class="photo-uploader">
<div class="photo-list">
<van-uploader
multiple
v-if="isEditMode"
:capture="capture"
:max-count="maxCount"
:before-read="beforeRead"
:after-read="afterRead"
v-model="fileList"
preview-size="86"
@delete="deleteImg"
@click-upload="onClickUpload"
accept="image/*"
>
<div class="photo-button">
<span><van-icon name="plus" size="1.6rem" color="#ADB1B3" /></span>
<span class="photo-text">点击上传</span>
</div>
</van-uploader>
<div class="photo-preview" v-else>
<van-row gutter="16">
<div v-if="fileList.length === 0" class="empty-block">
暂无照片
</div>
<van-col v-else span="8" v-for="(item, index) in fileList" :key="index" style="padding-bottom: 1.6rem">
<div class="photo-item">
<van-image width="86" height="86" :src="item.url" @click="showOneImg(fileList, index)"></van-image>
</div>
</van-col>
</van-row>
</div>
</div>
</div>
</template>
<script>
import { ImagePreview } from 'vant'
import { cloneDeep, pick } from 'lodash'
import axios from 'axios'
import Sso from '@/sso' // 改成自己项目中获取 Token 的方法
export default {
props: {
isEditMode: {
type: Boolean,
defaut: true,
},
value: {
type: Array,
default: () => [],
},
maxCount: {
type: Number,
default: 15,
},
capture: {
type: String,
default: null, // 默认不选择
},
fileType: {
type: Array,
default: () => ['png', 'jpg', 'jpeg', 'heic', 'bmp'],
},
},
data() {
return {
uploadURL: process.env.VUE_APP_BASE_API + '/common/upload',
baseUrl: process.env.VUE_APP_BASE_API,
fileList: [],
}
},
computed: {
isUploading() {
let f = false
for (let i = 0, list = this.fileList; i < list.length; i++) {
if (list[i].status === 'uploading') {
f = true
break
}
}
return f
},
},
watch: {
value: {
handler(val) {
const list = cloneDeep(val)
if (this.fileList.length !== list.length) {
this.fileList = list
}
},
deep: true,
immediate: true,
},
fileList: {
handler(val, oldVal) {
this.$emit(
'input',
val.map((item) => pick(item, ['name', 'url', 'uid']))
)
},
deep: true,
},
},
methods: {
onClickUpload() {
const fun = () => {
// 客户端的方法
setTimeout(() => {
GoCom.maxWindow()
}, 300)
window.removeEventListener('focus', fun)
}
window.addEventListener('focus', fun)
},
beforeRead(file) {
if (!Array.isArray(file)) {
file = [file]
}
let error = 0
for (let i = 0; i < file.length; i++) {
const name = file[i].name.split('.')[file[i].name.split('.').length - 1]
if (this.fileType.indexOf(name.toLowerCase()) === -1) {
this.$toast(`格式错误,支持上传 ${this.fileType.join('、')} 格式的图片`)
error = 1
break
} else {
error = 0
}
}
if (error === 1) {
return false
} else {
if (this.fileList.length + file.length > 15) {
this.$toast('最多允许上传 15 张图片')
return false
} else {
return true
}
}
},
afterRead(res) {
if (!Array.isArray(res)) {
res = [res]
}
for (let i = 0; i < res.length; i++) {
let item = res[i]
item.status = 'uploading'
let formData = new FormData()
formData.append('file', item.file)
axios
.post(this.uploadURL, formData, {
headers: {
Authorization: 'Bearer ' + Sso.getToken(),
'Content-Type': 'multipart/form-data',
},
})
.then((response) => {
if (response.data.code === 200) {
Object.assign(item, {
status: 'done',
name: this.baseUrl + response.data.fileName,
url: this.baseUrl + response.data.fileName,
uid: Date.now(),
})
} else {
this.uploadFailed(item, response.data.msg)
}
})
.catch(() => {
this.uploadFailed(item, '网络错误,上传失败!')
})
}
},
uploadFailed(item, msg) {
item.status = 'failed'
this.$toast(msg)
},
deleteImg(code) {
const list = this.fileList
let item
let i
let found = false
for (i = 0; i < list.length; i++) {
item = list[i]
if (item.name === code.name) {
found = true
break
}
}
if (found) this.fileList = [...list.slice(0, i), ...list.slice(i + 1)]
},
showOneImg(fileList, index) {
let list = fileList.map((e) => {
return e.url
})
ImagePreview({
images: list,
startPosition: index,
})
},
},
}
</script>
<style scoped lang="scss">
.photo-uploader .photo-list {
padding-top: 0.8rem;
}
.photo-uploader .photo-list .photo-preview .photo-item {
position: relative;
padding: 0.8rem;
border: 1px solid rgba(0, 28, 77, 0.08);
border-radius: 0.4rem;
display: flex;
justify-content: center;
align-items: center;
}
.photo-uploader .photo-list .photo-button {
width: 9.6rem;
height: 9.6rem;
margin-bottom: 1.6rem;
background: #f7f8fb;
box-sizing: border-box;
border-radius: 0.4rem;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
.photo-uploader .photo-list .photo-button .photo-text {
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 22px;
color: #adb1b3;
}
.photo-uploader ::v-deep .van-uploader__preview {
width: 9.6rem;
height: 9.6rem;
border: 1px solid rgba(0, 28, 77, 0.08);
margin: 0 1rem 1rem 0;
border-radius: 0.4rem;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.photo-uploader ::v-deep .van-uploader__preview img {
width: 8.6rem;
height: 8.6rem;
}
.photo-uploader ::v-deep .van-uploader__preview .van-uploader__preview-delete {
width: 2rem;
height: 2rem;
border-radius: 50%;
background-color: #adb1b3;
display: flex;
align-items: center;
position: absolute;
top: -1rem;
right: -1rem;
}
.photo-uploader ::v-deep .van-uploader__preview .van-uploader__preview-delete .van-uploader__preview-delete-icon {
font-size: 16px;
color: #fff;
font-weight: 600;
position: absolute;
top: 0.2rem;
right: 0.2rem;
}
.empty-block {
padding-bottom: 1.6rem;
}
</style>
猜你喜欢
最新发布
github访问慢解决方法
2024-11-10 13:52:54
我TM终于找到工作了
2024-06-02 14:48:43
我TM服务器又被攻击了
2024-04-12 19:28:34
Jenkins使用http方式配置github项目
2024-03-19 18:10:08
CentOS安装Jenkins服务
2024-03-18 17:23:08
终于特喵的帮朋友把微信小程序第一阶段做完了
2024-03-03 19:21:25
2023年终总结
2023-12-20 21:30:52
CentOS7 安装Node.js v14
2023-11-16 09:57:36
npm 安装依赖报错 npm ERR | gyp verb
2023-08-23 15:08:39
electron-builder + vue 搭建桌面应用
2023-06-08 10:54:28