feat: 图片拖拽问题处理,VueDraggable不支持jsx写法
This commit is contained in:
@ -220,9 +220,9 @@ export default {
|
||||
</div>
|
||||
</header>
|
||||
{loading.value ? (
|
||||
<Spin spinning={loading.value} class="h-500px w-full flex justify-center items-center" size={60} />
|
||||
<Spin spinning={loading.value} class="flex-1 w-full flex justify-center items-center" size={60} />
|
||||
) : (
|
||||
<div class={`page-wrap relative ${isExpand.value ? 'expand' : ''}`}>
|
||||
<section class={`page-wrap relative ${isExpand.value ? 'expand' : ''}`}>
|
||||
<div class="fold-box cursor-pointer" onClick={() => (isExpand.value = true)}>
|
||||
<icon-menu-fold size={20} class="color-#55585F hover:color-#6D4CFE" />
|
||||
</div>
|
||||
@ -261,7 +261,7 @@ export default {
|
||||
onDeleteComment={onDeleteComment}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: #fff;
|
||||
.explore-detail-wrap {
|
||||
min-height: 500px;
|
||||
width: 684px;
|
||||
|
||||
@ -50,10 +50,10 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{loading.value ? (
|
||||
<Spin spinning={loading.value} class="h-500px w-full flex justify-center items-center" size={60} />
|
||||
) : (
|
||||
<section class="page-wrapper flex justify-center">
|
||||
{loading.value ? (
|
||||
<Spin spinning={loading.value} class="w-full flex justify-center items-center" size={60} />
|
||||
) : (
|
||||
<div class="explore-container">
|
||||
<div class="explore-list-wrap pt-24px pb-28px">
|
||||
<TextOverTips context={`${works.value[0]?.title}等${works.value.length}个文件`} class="mb-8px" />
|
||||
@ -99,8 +99,8 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
}
|
||||
}
|
||||
.page-wrapper {
|
||||
background: #fff;
|
||||
min-height: calc(100vh - $navbar-height);
|
||||
.explore-container {
|
||||
width: 1200px;
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<a-form-item field="files">
|
||||
<template #label>
|
||||
<div class="flex items-center">
|
||||
<span class="cts !color-#211F24 mr-4px">图片</span>
|
||||
<span class="cts mr-8px !color-#939499">{{ `(${files.length ?? 0}/18)` }}</span>
|
||||
<span class="cts !color-#939499">第一张为首图,支持拖拽排序</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex items-center">
|
||||
<VueDraggable v-model="files" class="grid grid-cols-7 gap-y-8px" @end="handleChange" draggable=".group">
|
||||
<div
|
||||
v-for="(file, index) in files"
|
||||
:key="file.url"
|
||||
class="group relative cursor-move overflow-visible py-8px pr-8px"
|
||||
>
|
||||
<div class="group-container relative rounded-8px w-100px h-100px">
|
||||
<img :src="file.url" class="object-cover w-full h-full border-1px border-#E6E6E8 rounded-8px" />
|
||||
<icon-close-circle-fill
|
||||
:size="16"
|
||||
class="absolute top--8px right--8px cursor-pointer hidden color-#939499 hidden group-hover:block z-50"
|
||||
@click="() => handleDeleteFile(index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<a-upload
|
||||
v-if="files.length < 18"
|
||||
ref="uploadRef"
|
||||
action="/"
|
||||
draggable
|
||||
:custom-request="(option) => emit('upload', option)"
|
||||
accept=".jpg,.jpeg,.png,.gif,.webp"
|
||||
:show-file-list="false"
|
||||
multiple
|
||||
class="!flex !items-center"
|
||||
:limit="18 - files.length"
|
||||
>
|
||||
<template #upload-button>
|
||||
<div class="upload-box">
|
||||
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
||||
<span class="cts !color-#211F24">上传图片</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-upload>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
|
||||
const props = defineProps({
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const files = ref([]);
|
||||
const uploadRef = ref(null);
|
||||
|
||||
const emit = defineEmits(['change', 'delete', 'upload']);
|
||||
|
||||
const handleChange = () => {
|
||||
emit('change', files.value);
|
||||
};
|
||||
|
||||
const handleDeleteFile = (index) => {
|
||||
emit('delete', index);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.files,
|
||||
(newVal) => {
|
||||
files.value = newVal;
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.upload-box {
|
||||
display: flex;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
border: 1px dashed var(--Border-1, #d7d7d9);
|
||||
background: var(--BG-200, #f2f3f5);
|
||||
&:hover {
|
||||
background: var(--Primary-1, #e6e6e8);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -4,6 +4,7 @@ import { Form, FormItem, Input, Textarea, Upload, Message as AMessage, Button }
|
||||
import CommonSelect from '@/components/common-select';
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
import TextOverTips from '@/components/text-over-tips';
|
||||
import ImgBox from './img-box';
|
||||
|
||||
import { formatFileSize, getVideoInfo, formatDuration, formatUploadSpeed } from '@/utils/tools';
|
||||
import { getProjectList } from '@/api/all/propertyMarketing';
|
||||
@ -293,60 +294,9 @@ export default {
|
||||
);
|
||||
};
|
||||
|
||||
const renderImage = () => {
|
||||
return (
|
||||
<FormItem
|
||||
field="files"
|
||||
v-slots={{
|
||||
label: () => (
|
||||
<div class="flex items-center">
|
||||
<span class="cts !color-#211F24 mr-4px">图片</span>
|
||||
<span class="cts mr-8px !color-#939499">{`(${formData.value.files?.length ?? 0}/18)`}</span>
|
||||
<span class="cts !color-#939499">第一张为首图,支持拖拽排序</span>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
{/* 已上传的图片列表 */}
|
||||
<VueDraggable v-model={formData.value.files} class="grid grid-cols-7 gap-y-8px">
|
||||
{formData.value.files?.map((file, index) => (
|
||||
<div key={index} class="group relative cursor-move overflow-visible py-8px pr-8px">
|
||||
<div class="group-container relative rounded-8px w-100px h-100px">
|
||||
<img src={file.url} class=" object-cover w-full h-full border-1px border-#E6E6E8 rounded-8px" />
|
||||
<icon-close-circle-fill
|
||||
size={16}
|
||||
class="absolute top--8px right--8px cursor-pointer hidden color-#939499 hidden group-hover:block z-50"
|
||||
onClick={() => handleDeleteFile(index)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</VueDraggable>
|
||||
{formData.value.files?.length < 18 && (
|
||||
<Upload
|
||||
ref={uploadRef}
|
||||
action="/"
|
||||
draggable
|
||||
custom-request={uploadImage}
|
||||
accept=".jpg,.jpeg,.png,.gif,.webp"
|
||||
show-file-list={false}
|
||||
multiple
|
||||
limit={18 - formData.value.files?.length}
|
||||
>
|
||||
{{
|
||||
'upload-button': () => (
|
||||
<div class="upload-box">
|
||||
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
||||
<span class="cts !color-#211F24">上传图片</span>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
</Upload>
|
||||
)}
|
||||
</div>
|
||||
</FormItem>
|
||||
);
|
||||
const handleImagesChange = (files) => {
|
||||
formData.value.files = cloneDeep(files);
|
||||
onChange();
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
@ -392,7 +342,16 @@ export default {
|
||||
auto-size={{ minRows: 7, maxRows: 12 }}
|
||||
/>
|
||||
</FormItem>
|
||||
{isVideo.value ? renderVideo() : renderImage()}
|
||||
{isVideo.value ? (
|
||||
renderVideo()
|
||||
) : (
|
||||
<ImgBox
|
||||
files={formData.value.files}
|
||||
onChange={handleImagesChange}
|
||||
onDelete={handleDeleteFile}
|
||||
onUpload={uploadImage}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* <FormItem label="所属项目" field="project_ids">
|
||||
<CommonSelect
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<a-form-item field="files">
|
||||
<template #label>
|
||||
<div class="flex items-center">
|
||||
<span class="cts !color-#211F24 mr-4px">图片</span>
|
||||
<span class="cts mr-8px !color-#939499">{{ `(${files.length ?? 0}/18)` }}</span>
|
||||
<span class="cts !color-#939499">第一张为首图,支持拖拽排序</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex items-center">
|
||||
<VueDraggable v-model="files" class="grid grid-cols-7 gap-y-8px" @end="handleChange" draggable=".group">
|
||||
<div
|
||||
v-for="(file, index) in files"
|
||||
:key="file.url"
|
||||
class="group relative cursor-move overflow-visible py-8px pr-8px"
|
||||
>
|
||||
<div class="group-container relative rounded-8px w-100px h-100px">
|
||||
<img :src="file.url" class="object-cover w-full h-full border-1px border-#E6E6E8 rounded-8px" />
|
||||
<icon-close-circle-fill
|
||||
:size="16"
|
||||
class="absolute top--8px right--8px cursor-pointer hidden color-#939499 hidden group-hover:block z-50"
|
||||
@click="() => handleDeleteFile(index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<a-upload
|
||||
v-if="files.length < 18"
|
||||
ref="uploadRef"
|
||||
action="/"
|
||||
draggable
|
||||
:custom-request="(option) => emit('upload', option)"
|
||||
accept=".jpg,.jpeg,.png,.gif,.webp"
|
||||
:show-file-list="false"
|
||||
multiple
|
||||
class="!flex !items-center"
|
||||
:limit="18 - files.length"
|
||||
>
|
||||
<template #upload-button>
|
||||
<div class="upload-box">
|
||||
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
||||
<span class="cts !color-#211F24">上传图片</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-upload>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
|
||||
const props = defineProps({
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const files = ref([]);
|
||||
const uploadRef = ref(null);
|
||||
|
||||
const emit = defineEmits(['change', 'delete', 'upload']);
|
||||
|
||||
const handleChange = () => {
|
||||
emit('change', files.value);
|
||||
};
|
||||
|
||||
const handleDeleteFile = (index) => {
|
||||
emit('delete', index);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.files,
|
||||
(newVal) => {
|
||||
files.value = newVal;
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.upload-box {
|
||||
display: flex;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
border: 1px dashed var(--Border-1, #d7d7d9);
|
||||
background: var(--BG-200, #f2f3f5);
|
||||
&:hover {
|
||||
background: var(--Primary-1, #e6e6e8);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -4,6 +4,7 @@ import { Form, FormItem, Input, Textarea, Upload, Message as AMessage, Button }
|
||||
import CommonSelect from '@/components/common-select';
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
import TextOverTips from '@/components/text-over-tips';
|
||||
import ImgBox from './img-box';
|
||||
|
||||
import { formatFileSize, getVideoInfo, formatDuration, formatUploadSpeed } from '@/utils/tools';
|
||||
import { getProjectList } from '@/api/all/propertyMarketing';
|
||||
@ -293,60 +294,9 @@ export default {
|
||||
);
|
||||
};
|
||||
|
||||
const renderImage = () => {
|
||||
return (
|
||||
<FormItem
|
||||
field="files"
|
||||
v-slots={{
|
||||
label: () => (
|
||||
<div class="flex items-center">
|
||||
<span class="cts !color-#211F24 mr-4px">图片</span>
|
||||
<span class="cts mr-8px !color-#939499">{`(${formData.value.files?.length ?? 0}/18)`}</span>
|
||||
<span class="cts !color-#939499">第一张为首图,支持拖拽排序</span>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
{/* 已上传的图片列表 */}
|
||||
<VueDraggable v-model={formData.value.files} class="grid grid-cols-7 gap-y-8px">
|
||||
{formData.value.files?.map((file, index) => (
|
||||
<div key={index} class="group relative cursor-move overflow-visible py-8px pr-8px">
|
||||
<div class="group-container relative rounded-8px w-100px h-100px">
|
||||
<img src={file.url} class=" object-cover w-full h-full border-1px border-#E6E6E8 rounded-8px" />
|
||||
<icon-close-circle-fill
|
||||
size={16}
|
||||
class="absolute top--8px right--8px cursor-pointer hidden color-#939499 hidden group-hover:block z-50"
|
||||
onClick={() => handleDeleteFile(index)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</VueDraggable>
|
||||
{formData.value.files?.length < 18 && (
|
||||
<Upload
|
||||
ref={uploadRef}
|
||||
action="/"
|
||||
draggable
|
||||
custom-request={uploadImage}
|
||||
accept=".jpg,.jpeg,.png,.gif,.webp"
|
||||
show-file-list={false}
|
||||
multiple
|
||||
limit={18 - formData.value.files?.length}
|
||||
>
|
||||
{{
|
||||
'upload-button': () => (
|
||||
<div class="upload-box">
|
||||
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
||||
<span class="cts !color-#211F24">上传图片</span>
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
</Upload>
|
||||
)}
|
||||
</div>
|
||||
</FormItem>
|
||||
);
|
||||
const handleImagesChange = (files) => {
|
||||
formData.value.files = cloneDeep(files);
|
||||
onChange();
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
@ -392,7 +342,16 @@ export default {
|
||||
auto-size={{ minRows: 7, maxRows: 12 }}
|
||||
/>
|
||||
</FormItem>
|
||||
{isVideo.value ? renderVideo() : renderImage()}
|
||||
{isVideo.value ? (
|
||||
renderVideo()
|
||||
) : (
|
||||
<ImgBox
|
||||
files={formData.value.files}
|
||||
onChange={handleImagesChange}
|
||||
onDelete={handleDeleteFile}
|
||||
onUpload={uploadImage}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* <FormItem label="所属项目" field="project_ids">
|
||||
<CommonSelect
|
||||
|
||||
Reference in New Issue
Block a user