137 lines
3.2 KiB
Vue
137 lines
3.2 KiB
Vue
<template>
|
|
<div class="pi-asset">
|
|
<div class="file-item" v-for="(item, index) in value" :key="index" :style="style">
|
|
<el-image v-if="obj.isImg(item)" :src="item" :style="style" :preview-src-list="[item]" fit="cover"
|
|
preview-teleported :z-index="9999"></el-image>
|
|
<pi-player v-else-if="obj.isVideo(item)" :src="item" :options="videoOptions"></pi-player>
|
|
<el-icon v-else :style="style" style="color: #409eff;" :size="32">
|
|
<component :is="'pi-icon-task'"/>
|
|
</el-icon>
|
|
<div class="file-item-delete" @click="del(index)">
|
|
<el-icon>
|
|
<component :is="'el-icon-delete'" color="#ffffff"/>
|
|
</el-icon>
|
|
</div>
|
|
</div>
|
|
<span class="pi-upload" :style="style" v-if="limit > value.length" @click="openDialog">
|
|
<el-icon><component :is="'el-icon-plus'"/></el-icon>
|
|
</span>
|
|
<picker-dialog v-if="dialogVisible" ref="pickerRef" @success="saveSuccess" @closed="dialogVisible=false"
|
|
:max="limit-value.length" :multiple="limit>1" :type="type"></picker-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import pickerDialog from "./picker.vue";
|
|
import assetConfig from "@/config/asset"
|
|
import piPlayer from '@/components/piPlayer'
|
|
import {nextTick, ref, watch} from "vue";
|
|
|
|
const emit = defineEmits(['update:modelValue'])
|
|
const props = defineProps({
|
|
modelValue: null,
|
|
limit: {type: Number, default: 1},
|
|
height: {type: Number, default: 148},
|
|
width: {type: Number, default: 148},
|
|
type: {type: String, default: "image"}
|
|
})
|
|
|
|
let dialogVisible = ref(false)
|
|
const pickerRef = ref(null)
|
|
let value = ref([])
|
|
let style = ref({
|
|
width: props.width + "px",
|
|
height: props.height + "px"
|
|
})
|
|
let obj = ref(assetConfig)
|
|
let videoOptions = ref({
|
|
pip: true
|
|
})
|
|
|
|
watch(value, (val) => {
|
|
if (props.limit > 1) {
|
|
emit('update:modelValue', val)
|
|
} else {
|
|
emit('update:modelValue', val[0])
|
|
}
|
|
}, {deep: true, immediate: false})
|
|
|
|
watch(() => props.modelValue, (val) => {
|
|
if (props.limit > 1) {
|
|
if (!val || val.length <= 0) return;
|
|
value.value = val
|
|
} else {
|
|
if (!val) return;
|
|
value.value = val ? [val] : []
|
|
}
|
|
}, {deep: true, immediate: true})
|
|
|
|
function saveSuccess(val) {
|
|
if (props.limit > 1) {
|
|
value.value = value.value.concat(val)
|
|
} else {
|
|
value.value = [val]
|
|
}
|
|
}
|
|
|
|
function del(index) {
|
|
value.value.splice(index, 1)
|
|
}
|
|
|
|
function openDialog() {
|
|
dialogVisible.value = true
|
|
nextTick(() => {
|
|
pickerRef.value.open()
|
|
})
|
|
}
|
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.pi-asset {
|
|
width: 100%;
|
|
display: contents;
|
|
}
|
|
|
|
.pi-asset .file-item {
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
position: relative;
|
|
}
|
|
|
|
.pi-asset .file-item:hover .file-item-delete {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.pi-asset .file-item .file-item-delete {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
background: #F56C6C;
|
|
line-height: initial;
|
|
width: 25px;
|
|
height: 25px;
|
|
display: none;
|
|
cursor: pointer;
|
|
z-index: 999;
|
|
}
|
|
|
|
.pi-asset .pi-upload {
|
|
border: 1px dashed var(--el-border-color-darker);
|
|
background-color: var(--el-fill-color-lighter);
|
|
cursor: pointer;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
color: var(--el-text-color-secondary);
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.pi-asset .pi-upload:hover {
|
|
border-color: var(--el-color-primary);
|
|
}
|
|
</style>
|