admin/src/components/piAsset/index.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>