emis-sapp/components/tpx-upload/tpx-upload.vue
2024-01-27 17:56:52 +08:00

236 lines
4.6 KiB
Vue

<template>
<view :style="`${customstyle};flex-direction: ${direction};`" class="up-cont">
<view v-for="(item, index) in list" :style="`${compItemstyle}`">
<view class="cdimg" @click="handleItem(index)">
<tpx-image v-if="fileType==fileTypeEnum.image" :src="item" :height="height" :width="width"></tpx-image>
<video v-if="fileType==fileTypeEnum.video" :src="item"></video>
<view v-if="fileType==fileTypeEnum.all">{{item}}</view>
<view v-if="!disabled" @click.stop="handleDel(index)" class="delIcon">
<u-icon name="close-circle-fill" size="32" color=""></u-icon>
</view>
</view>
</view>
<view v-if="list.length < maxLen" style="width: 100%;">
<view v-if="!isSlot" @click="handleChooseFile" class="camer-btn" :style="`width:${width}rpx;height:${height}rpx;`">
<template v-if="btnText">
<u-icon name="plus" size="40"></u-icon>
<text class="pt-10">{{btnText}}</text>
</template>
<template v-else>
<view class="">
<u-icon name="camera" size="50"></u-icon>
</view>
<view class="font-22">
<text>上传</text>
<text v-if="fileType==fileTypeEnum.image">图片</text>
<text v-if="fileType==fileTypeEnum.video">视频</text>
<text v-if="fileType==fileTypeEnum.all">文件</text>
</view>
</template >
</view>
<view v-if="isSlot" @click="handleChooseFile" style="width: 100%;">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
import { coreMultiUploadFile } from "@/common/upload"
import { showToast } from "@/common/untool"
const fileTypeEnum = {
all: "all",
image: "image",
video: "video",
}
export default {
computed: {
list() {
let val = this.value
let res = []
if (typeof val == "object") {
res = val
}
if (typeof val == 'string' && val !== '') {
res = val.split(",")
}
return res
},
compItemstyle(){
let style = `margin-bottom: 16rpx;margin-right: 16rpx;`
if(this.direction == "row") {
// style += `width:${this.width}rpx;height:${this.height}rpx;`
}
return `${this.itemstyle};${style};`
}
},
props: {
customstyle: {
default () {
return ''
}
},
itemstyle: {
default () {
return ''
}
},
width: {
default () {
return 168
}
},
height: {
default () {
return 168
}
},
direction: {
default () {
return 'row'
}
},
btnText: {
default () {
return ''
}
},
value: {
default () {
return ''
}
},
fileType: {
default () {
return fileTypeEnum.image
}
},
pickMaxLen: { // 一次最多选择个数
default () {
return 5
}
},
maxLen: { // 最大个数
default () {
return 1
}
},
minLen: { // 最小个数
default () {
return 1
}
},
disabled: {
default () {
return false
}
},
isSlot: {
default () {
return false
}
}
},
data() {
return {
fileTypeEnum: Object.assign({}, fileTypeEnum),
}
},
created() {
},
onHide() {
},
destroyed() {},
methods: {
doChooseFile(opt = {}) {
const that = this
const actMap = {
image: "chooseImage",
video: "chooseVideo",
}
return coreMultiUploadFile(actMap[this.fileType], opt)
},
handlePreview(index) {
uni.previewImage({
current: index,
urls: [
...this.list
]
})
},
handleDel(index){
this.list.splice(index, 1)
this.triggerChanged(this.list)
},
handleItem(index) {
this.handlePreview(index)
},
handleChooseFile: function() {
let that = this
let { maxLen, pickMaxLen, list } = this
let count = pickMaxLen
if (list.length + pickMaxLen > maxLen) {
count = maxLen - list.length
}
if (count <= 0) {
return showToast(`最多上传${maxLen}个`)
}
this.doChooseFile({
count
}).then((res) => {
list = list.concat(res)
that.triggerChanged(list)
})
},
triggerChanged(list) {
let val = list
if(this.maxLen == 1) {
val = list[0] || ''
}
this.$emit('change', val)
this.$emit('update:value', val)
}
}
}
</script>
<style scoped lang="scss">
.up-cont{
width: 100%;
display: flex;
flex-wrap: wrap;
}
.camer-btn {
border: 2rpx solid #EFEFEF;
border-radius: 6rpx;
background: #F8F8F8;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 20rpx;
}
.cdimg {
position: relative;
.delIcon{
position: absolute;
height: 46rpx;
width: 46rpx;
right: -10rpx;
top: -10rpx;
.u-icon{
justify-content: end;
}
}
}
</style>