文件选择器添加插槽,修复在下拉框多选情况下数据不同步的bug

This commit is contained in:
阿辉
2024-12-05 11:56:15 +08:00
parent 81d2fac8b6
commit d8f41919ea

View File

@@ -1,6 +1,7 @@
<template> <template>
<div style="width: 100%;" :style="props.style"> <div style="width: 100%;" :class="props.class" :style="props.style">
<div v-show="props.showInput" style="width: 100%;" :class="props.class" :style="props.inputStyle"> <slot name="input" v-bind="{}">
<div v-if="props.showInput" style="width: 100%;" :class="props.inputClass" :style="props.inputStyle">
<el-select v-if="props.inputType === 'selector'" v-model="data" suffix-icon="arrow-down" clearable <el-select v-if="props.inputType === 'selector'" v-model="data" suffix-icon="arrow-down" clearable
:multiple="props.multiple" placeholder="请选择文件" @click="selectVisiable = true && !props.disabled" :multiple="props.multiple" placeholder="请选择文件" @click="selectVisiable = true && !props.disabled"
:disabled="props.disabled" @clear="selectedInit" @remove-tag="selectedInit"> :disabled="props.disabled" @clear="selectedInit" @remove-tag="selectedInit">
@@ -64,6 +65,7 @@
</el-icon> </el-icon>
</div> </div>
</div> </div>
</slot>
<el-dialog v-model="selectVisiable" :draggable="false" width="50%" :align-center="false" :append-to-body="true" <el-dialog v-model="selectVisiable" :draggable="false" width="50%" :align-center="false" :append-to-body="true"
@open="if (listData.length === 0) listRequest();" @close="onClose" @closed="onClosed" modal-class="_overlay"> @open="if (listData.length === 0) listRequest();" @close="onClose" @closed="onClosed" modal-class="_overlay">
<template #header> <template #header>
@@ -117,7 +119,8 @@
<div ref="listContainerRef" class="listContainer" v-else> <div ref="listContainerRef" class="listContainer" v-else>
<div v-for="item, index in listData" :key="index" @click="onItemClick($event)" :data-id="item[props.valueKey]" <div v-for="item, index in listData" :key="index" @click="onItemClick($event)" :data-id="item[props.valueKey]"
:style="{ width: (props.itemSize || 100) + 'px', cursor: props.selectable ? 'pointer' : 'normal' }"> :style="{ width: (props.itemSize || 100) + 'px', cursor: props.selectable ? 'pointer' : 'normal' }">
<FileItem :fileData="item" :api="fileApi" :showClose="tabsActived < 4 || isSuperTenent" @onDelFile="listRequest(); listRequestAll();" /> <FileItem :fileData="item" :api="fileApi" :showClose="tabsActived < 4 || isSuperTenent"
@onDelFile="listRequest(); listRequestAll();" />
</div> </div>
</div> </div>
<div class="listPaginator"> <div class="listPaginator">
@@ -174,7 +177,8 @@ const TypeLabel = ['图片', '视频', '音频', '文件']
const AcceptList = ['image/*', 'video/*', 'audio/*', '']; const AcceptList = ['image/*', 'video/*', 'audio/*', ''];
const props = defineProps({ const props = defineProps({
modelValue: {}, modelValue: {},
class: { type: String, default: '' }, class: { type: Object as PropType<String | Object>, default: '' },
inputClass: { type: Object as PropType<String | Object>, default: '' },
style: { type: Object as PropType<Object | string>, default: {} }, style: { type: Object as PropType<Object | string>, default: {} },
inputStyle: { type: Object as PropType<Object | string>, default: {} }, inputStyle: { type: Object as PropType<Object | string>, default: {} },
disabled: { type: Boolean, default: false }, disabled: { type: Boolean, default: false },
@@ -263,7 +267,7 @@ const onItemClick = async (e: MouseEvent) => {
if (props.multiple) { if (props.multiple) {
if (target.classList.contains('active')) { target.classList.remove('active'); flat = -1; } if (target.classList.contains('active')) { target.classList.remove('active'); flat = -1; }
else { target.classList.add('active'); flat = 1; } else { target.classList.add('active'); flat = 1; }
if (data.value) { if (data.value.length) {
if (flat === 1) data.value.push(fileId); if (flat === 1) data.value.push(fileId);
else data.value.splice(data.value.indexOf(fileId), 1); else data.value.splice(data.value.indexOf(fileId), 1);
} else data.value = [fileId]; } else data.value = [fileId];
@@ -279,7 +283,7 @@ const onItemClick = async (e: MouseEvent) => {
// 每次列表刷新都得更新一下选择状态,因为所有标签页共享列表 // 每次列表刷新都得更新一下选择状态,因为所有标签页共享列表
const selectedInit = async () => { const selectedInit = async () => {
if (!props.selectable) return; if (!props.selectable) return;
await nextTick(); await nextTick(); // 不等待一次不会刷新
for (let i of (listContainerRef.value?.children || [])) { for (let i of (listContainerRef.value?.children || [])) {
i.classList.remove('active'); i.classList.remove('active');
let fid = (i as HTMLElement).dataset.id; let fid = (i as HTMLElement).dataset.id;
@@ -363,7 +367,11 @@ const confirmNetUrl = () => {
// fs-crud部分 // fs-crud部分
const data = ref<any>(null); const data = ref<any>(null);
const emit = defineEmits(['update:modelValue', 'onSave', 'onClose', 'onClosed']); const emit = defineEmits(['update:modelValue', 'onSave', 'onClose', 'onClosed']);
watch(() => props.modelValue, (val) => { data.value = val; }, { immediate: true }); watch(
() => props.modelValue,
(val) => data.value = val,
{ immediate: true }
);
const { ui } = useUi(); const { ui } = useUi();
const formValidator = ui.formItem.injectFormItemContext(); const formValidator = ui.formItem.injectFormItemContext();
const onDataChange = (value: any) => { const onDataChange = (value: any) => {