131 lines
2.3 KiB
Vue
131 lines
2.3 KiB
Vue
|
|
<template>
|
||
|
|
<view>
|
||
|
|
<uni-file-picker
|
||
|
|
v-model="fileList"
|
||
|
|
file-mediatype="image"
|
||
|
|
:limit="limit"
|
||
|
|
:image-styles="imageStyles"
|
||
|
|
:auto-upload="false"
|
||
|
|
@select="onSelect"
|
||
|
|
@delete="onDelete"
|
||
|
|
/>
|
||
|
|
</view>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
export default {
|
||
|
|
name: 'ImageUpload',
|
||
|
|
props: {
|
||
|
|
value: {
|
||
|
|
type: String,
|
||
|
|
default: ''
|
||
|
|
},
|
||
|
|
limit: {
|
||
|
|
type: Number,
|
||
|
|
default: 9
|
||
|
|
}
|
||
|
|
},
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
fileList: []
|
||
|
|
}
|
||
|
|
},
|
||
|
|
watch: {
|
||
|
|
value: {
|
||
|
|
immediate: true,
|
||
|
|
handler(val) {
|
||
|
|
// 字符串转数组
|
||
|
|
if (val) {
|
||
|
|
this.fileList = val.split(',').filter(Boolean).map(url => ({ url }))
|
||
|
|
} else {
|
||
|
|
this.fileList = []
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
fileList: {
|
||
|
|
deep: true,
|
||
|
|
handler(val) {
|
||
|
|
// 数组转字符串
|
||
|
|
const urls = val.map(item => item.url).filter(Boolean).join(',')
|
||
|
|
this.$emit('input', urls)
|
||
|
|
this.$emit('update:value', urls)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
onSelect(e) {
|
||
|
|
if (e.tempFiles) {
|
||
|
|
const files = e.tempFiles.map(f => ({ url: f.path || f.url }))
|
||
|
|
this.fileList = this.fileList.concat(files)
|
||
|
|
}
|
||
|
|
},
|
||
|
|
onDelete(e) {
|
||
|
|
if (e.tempFilePaths) {
|
||
|
|
this.fileList = e.tempFilePaths.map(url => ({ url }))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
computed: {
|
||
|
|
imageStyles() {
|
||
|
|
return {
|
||
|
|
width: 80,
|
||
|
|
height: 80,
|
||
|
|
borderRadius: 8
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.upload-image {
|
||
|
|
display: flex;
|
||
|
|
flex-wrap: wrap;
|
||
|
|
}
|
||
|
|
.image-list {
|
||
|
|
display: flex;
|
||
|
|
flex-wrap: wrap;
|
||
|
|
gap: 16rpx;
|
||
|
|
}
|
||
|
|
.image-item {
|
||
|
|
position: relative;
|
||
|
|
width: 160rpx;
|
||
|
|
height: 160rpx;
|
||
|
|
margin-bottom: 16rpx;
|
||
|
|
}
|
||
|
|
.image {
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
border-radius: 8rpx;
|
||
|
|
object-fit: cover;
|
||
|
|
}
|
||
|
|
.delete-btn {
|
||
|
|
position: absolute;
|
||
|
|
top: -12rpx;
|
||
|
|
right: -12rpx;
|
||
|
|
background: rgba(0,0,0,0.5);
|
||
|
|
color: #fff;
|
||
|
|
border-radius: 50%;
|
||
|
|
width: 32rpx;
|
||
|
|
height: 32rpx;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
font-size: 28rpx;
|
||
|
|
z-index: 2;
|
||
|
|
}
|
||
|
|
.add-btn {
|
||
|
|
width: 160rpx;
|
||
|
|
height: 160rpx;
|
||
|
|
background: #f5f5f5;
|
||
|
|
border: 1rpx dashed #ccc;
|
||
|
|
border-radius: 8rpx;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
font-size: 80rpx;
|
||
|
|
color: #bbb;
|
||
|
|
margin-bottom: 16rpx;
|
||
|
|
}
|
||
|
|
</style>
|