文件选择器添加表单类型选项,目前支持selector和image类型
This commit is contained in:
@@ -1,10 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-select v-show="props.selectable" v-model="data" suffix-icon="arrow-down" clearable :multiple="props.multiple"
|
<div v-show="props.showInput" style="width: 100%;">
|
||||||
placeholder="请选择文件" @click="selectVisiable = true" @clear="selectedInit" @remove-tag="selectedInit">
|
<el-select v-if="props.inputType === 'selector'" v-model="data" suffix-icon="arrow-down" clearable
|
||||||
|
:multiple="props.multiple" placeholder="请选择文件" @click="selectVisiable = true" @clear="selectedInit"
|
||||||
|
@remove-tag="selectedInit">
|
||||||
<el-option v-for="item, index in listAllData" :key="index" :value="item[props.valueKey]" :label="item.name" />
|
<el-option v-for="item, index in listAllData" :key="index" :value="item[props.valueKey]" :label="item.name" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
<div v-if="props.inputType === 'image'" style="position: relative;" class="imageInput"
|
||||||
|
:style="{ width: props.inputImageSize + 'px', height: props.inputImageSize + 'px' }">
|
||||||
|
<el-image :src="data" fit="scale-down" :style="{ width: props.inputImageSize + 'px', aspectRatio: '1 / 1' }">
|
||||||
|
<template #error>
|
||||||
|
<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;">
|
||||||
|
<el-icon :size="24">
|
||||||
|
<Plus />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
<div @click="selectVisiable = true" class="imageHover"></div>
|
||||||
|
<el-icon v-show="!!data" class="imageCloseHover" :size="16" @click="data = null; onDataChange(null);">
|
||||||
|
<Close />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<el-dialog v-model="selectVisiable" :draggable="false" width="50%" :align-center="false"
|
<el-dialog v-model="selectVisiable" :draggable="false" width="50%" :align-center="false"
|
||||||
@open="if (listData.length === 0) listRequest();" @closed="if (!props.selectable) clear();">
|
@open="if (listData.length === 0) listRequest();" @closed="clear">
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="el-dialog__title">文件选择</span>
|
<span class="el-dialog__title">文件选择</span>
|
||||||
<el-divider style="margin: 0;" />
|
<el-divider style="margin: 0;" />
|
||||||
@@ -18,8 +37,8 @@
|
|||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-row justify="space-between" class="headerBar">
|
<el-row justify="space-between" class="headerBar">
|
||||||
<el-span :span="16">
|
<el-span :span="16">
|
||||||
<el-input v-model="filterForm.name" :placeholder="`请输入${TypeLabel[tabsActived]}名`"
|
<el-input v-model="filterForm.name" :placeholder="`请输入${TypeLabel[tabsActived]}名`" prefix-icon="search"
|
||||||
prefix-icon="search" clearable @change="listRequest" />
|
clearable @change="listRequest" />
|
||||||
<div>
|
<div>
|
||||||
<el-tag v-if="props.multiple" type="primary" effect="light">
|
<el-tag v-if="props.multiple" type="primary" effect="light">
|
||||||
一共选中 {{ data?.length || 0 }} 个文件
|
一共选中 {{ data?.length || 0 }} 个文件
|
||||||
@@ -30,8 +49,7 @@
|
|||||||
<el-button type="default" circle icon="refresh" @click="listRequest" />
|
<el-button type="default" circle icon="refresh" @click="listRequest" />
|
||||||
<!-- 这里 show-file-list 和 clearFiles 一起使用确保不会显示上传列表 -->
|
<!-- 这里 show-file-list 和 clearFiles 一起使用确保不会显示上传列表 -->
|
||||||
<el-upload ref="uploadRef" :action="getBaseURL() + 'api/system/file/'" :multiple="false"
|
<el-upload ref="uploadRef" :action="getBaseURL() + 'api/system/file/'" :multiple="false"
|
||||||
:data="{ upload_method: 1 }" :drag="false" :show-file-list="false"
|
:data="{ upload_method: 1 }" :drag="false" :show-file-list="false" :accept="AcceptList[tabsActived]"
|
||||||
:accept="AcceptList[tabsActived]"
|
|
||||||
:on-success="() => { listRequest(); listRequestAll(); uploadRef.clearFiles(); }">
|
:on-success="() => { listRequest(); listRequestAll(); uploadRef.clearFiles(); }">
|
||||||
<el-button type="primary" icon="plus">上传{{ TypeLabel[tabsActived] }}</el-button>
|
<el-button type="primary" icon="plus">上传{{ TypeLabel[tabsActived] }}</el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
@@ -47,11 +65,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="listPaginator">
|
<div class="listPaginator">
|
||||||
<el-pagination background size="small" layout="total, sizes, prev, pager, next" :total="pageForm.total"
|
<el-pagination background size="small" layout="total, sizes, prev, pager, next" :total="pageForm.total"
|
||||||
v-model:page-size="pageForm.limit" :page-sizes="[10, 20, 30, 40, 50]"
|
v-model:page-size="pageForm.limit" :page-sizes="[10, 20, 30, 40, 50]" v-model:current-page="pageForm.page"
|
||||||
v-model:current-page="pageForm.page" :hide-on-single-page="false" @change="handlePageChange" />
|
:hide-on-single-page="false" @change="handlePageChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #footer v-if="props.selectable">
|
<template #footer v-if="props.showInput">
|
||||||
<el-button type="default" @click="selectVisiable = false">取消</el-button>
|
<el-button type="default" @click="selectVisiable = false">取消</el-button>
|
||||||
<el-button type="primary" @click="selectVisiable = false">确定</el-button>
|
<el-button type="primary" @click="selectVisiable = false">确定</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -79,13 +97,22 @@ const props = defineProps({
|
|||||||
// 是否可以多选,默认单选
|
// 是否可以多选,默认单选
|
||||||
multiple: { type: Boolean, default: false },
|
multiple: { type: Boolean, default: false },
|
||||||
|
|
||||||
// 是否可选,该参数用于控制是否显示select输入框。若赋值为false,则不会显示select输入框,也不会显示底部按钮
|
// 是否可选,该参数用于只上传和展示而不选择和绑定model的情况
|
||||||
// 如果不显示select输入框,则无法触发dialog,需要父组件通过修改本组件暴露的 selectVisiable 状态来控制dialog
|
|
||||||
selectable: { type: Boolean, default: true },
|
selectable: { type: Boolean, default: true },
|
||||||
|
|
||||||
|
// 该参数用于控制是否显示表单item。若赋值为false,则不会显示表单item,也不会显示底部按钮
|
||||||
|
// 如果不显示表单item,则无法触发dialog,需要父组件通过修改本组件暴露的 selectVisiable 状态来控制dialog
|
||||||
|
showInput: { type: Boolean, default: true },
|
||||||
|
|
||||||
|
// 表单item类型,不为selector是需要设置valueKey,否则可能获取不到媒体数据
|
||||||
|
inputType: { type: Object as PropType<'selector' | 'image' | 'video' | 'audio'>, default: 'selector' },
|
||||||
|
// inputType为image时生效
|
||||||
|
inputImageSize: { type: Number, default: 100 },
|
||||||
|
|
||||||
// v-model绑定的值是file数据的哪个key,默认是id
|
// v-model绑定的值是file数据的哪个key,默认是id
|
||||||
valueKey: { type: String, default: 'id' },
|
valueKey: { type: String, default: 'id' },
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
const selectVisiable = ref<boolean>(false);
|
const selectVisiable = ref<boolean>(false);
|
||||||
const tabsActived = ref<number>([3, 2, 1, 0][((props.tabsShow & (props.tabsShow - 1)) === 0) ? Math.log2(props.tabsShow) : 3]);
|
const tabsActived = ref<number>([3, 2, 1, 0][((props.tabsShow & (props.tabsShow - 1)) === 0) ? Math.log2(props.tabsShow) : 3]);
|
||||||
const fileApiPrefix = '/api/system/file/';
|
const fileApiPrefix = '/api/system/file/';
|
||||||
@@ -108,7 +135,11 @@ const listRequest = async () => {
|
|||||||
pageForm.limit = res.limit;
|
pageForm.limit = res.limit;
|
||||||
selectedInit();
|
selectedInit();
|
||||||
};
|
};
|
||||||
const listRequestAll = async () => { let res = await fileApi.GetAll(); listAllData.value = res.data; };
|
const listRequestAll = async () => {
|
||||||
|
if (props.inputType !== 'selector') return;
|
||||||
|
let res = await fileApi.GetAll();
|
||||||
|
listAllData.value = res.data;
|
||||||
|
};
|
||||||
// tab改变时触发
|
// tab改变时触发
|
||||||
const handleTabChange = (name: string) => { pageForm.page = 1; listRequest(); };
|
const handleTabChange = (name: string) => { pageForm.page = 1; listRequest(); };
|
||||||
// 分页器改变时触发
|
// 分页器改变时触发
|
||||||
@@ -169,7 +200,7 @@ const clear = () => {
|
|||||||
listData.value = [];
|
listData.value = [];
|
||||||
// all数据不能清,因为all只会在挂载的时候赋值一次
|
// all数据不能清,因为all只会在挂载的时候赋值一次
|
||||||
// listAllData.value = [];
|
// listAllData.value = [];
|
||||||
data.value = null;
|
// data.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -229,4 +260,30 @@ onMounted(() => listRequestAll());
|
|||||||
justify-items: center;
|
justify-items: center;
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.imageHover {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageHover:hover {
|
||||||
|
border-color: #c0c4cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageCloseHover {
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
top: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageCloseHover:hover {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user