Files
frontend/apps/web-antd/src/views/mall/promotion/components/draggable/index.vue
2025-11-04 17:56:30 +08:00

104 lines
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { IconifyIcon } from '@vben/icons';
import { cloneDeep } from '@vben/utils';
import { useVModel } from '@vueuse/core';
import { Button, Tooltip } from 'ant-design-vue';
import VueDraggable from 'vuedraggable';
/** 拖拽组件封装 */
defineOptions({ name: 'Draggable' });
/** 定义属性 */
const props = defineProps({
modelValue: {
type: Array,
default: () => [],
}, // 绑定值
emptyItem: {
type: Object,
default: () => ({}),
}, // 空的元素:点击添加按钮时,创建元素并添加到列表;默认为空对象
limit: {
type: Number,
default: Number.MAX_VALUE,
}, // 数量限制:默认为 0表示不限制
min: {
type: Number,
default: 1,
}, // 最小数量默认为1
});
const emit = defineEmits(['update:modelValue']);
const formData = useVModel(props, 'modelValue', emit);
/** 处理添加 */
function handleAdd() {
return formData.value.push(cloneDeep(props.emptyItem || {}));
}
/** 处理删除 */
const handleDelete = function (index: number) {
return formData.value.splice(index, 1);
};
</script>
<template>
<div class="text-sm text-gray-500">拖动左上角的小圆点可对其排序</div>
<VueDraggable
:list="formData"
:force-fallback="true"
:animation="200"
handle=".drag-icon"
class="mt-2"
item-key="index"
>
<template #item="{ element, index }">
<div class="mb-1 flex flex-col gap-1 rounded border border-gray-200 p-2">
<!-- 操作按钮区 -->
<div
class="-m-2 mb-1 flex flex-row items-center justify-between rounded-t p-2"
style="background-color: var(--ant-color-bg-container-secondary)"
>
<Tooltip title="拖动排序">
<IconifyIcon
icon="ic:round-drag-indicator"
class="drag-icon cursor-move text-gray-500"
/>
</Tooltip>
<Tooltip v-if="formData.length > min" title="删除">
<IconifyIcon
icon="ep:delete"
class="cursor-pointer text-red-500 hover:text-red-600"
@click="handleDelete(index)"
/>
</Tooltip>
</div>
<!-- 内容区 -->
<slot :element="element" :index="index"></slot>
</div>
</template>
</VueDraggable>
<Tooltip
:title="
limit > 0 && limit < Number.MAX_VALUE ? `最多添加${limit}个` : undefined
"
>
<Button
type="primary"
ghost
class="mt-1 w-full"
:disabled="limit > 0 && formData.length >= limit"
@click="handleAdd"
>
<template #icon>
<IconifyIcon icon="ep:plus" />
</template>
添加
</Button>
</Tooltip>
</template>
<style scoped lang="scss"></style>