refactor: 拖动插件更换为vue-draggable-plus
This commit is contained in:
parent
e89049ec76
commit
0b4e30e651
|
@ -60,12 +60,12 @@
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.0",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
|
"vue-draggable-plus": "^0.2.7",
|
||||||
"vue-echarts": "^6.6.1",
|
"vue-echarts": "^6.6.1",
|
||||||
"vue-i18n": "^9.3.0",
|
"vue-i18n": "^9.3.0",
|
||||||
"vue-router": "^4.2.4",
|
"vue-router": "^4.2.4",
|
||||||
"vue3-ace-editor": "^2.2.3",
|
"vue3-ace-editor": "^2.2.3",
|
||||||
"vue3-colorpicker": "^2.2.2",
|
"vue3-colorpicker": "^2.2.2"
|
||||||
"vuedraggable": "^4.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arco-plugins/vite-vue": "^1.4.5",
|
"@arco-plugins/vite-vue": "^1.4.5",
|
||||||
|
|
|
@ -5,144 +5,145 @@
|
||||||
:style="{ width: props.formWidth || '100%' }"
|
:style="{ width: props.formWidth || '100%' }"
|
||||||
>
|
>
|
||||||
<a-scrollbar class="overflow-y-auto" :style="{ 'max-height': props.maxHeight }">
|
<a-scrollbar class="overflow-y-auto" :style="{ 'max-height': props.maxHeight }">
|
||||||
<Draggable
|
<VueDraggable
|
||||||
tag="div"
|
v-model="form.list"
|
||||||
ghost-class="ghost"
|
ghost-class="ghost"
|
||||||
drag-class="dragChosenClass"
|
drag-class="dragChosenClass"
|
||||||
:disabled="!props.isShowDrag"
|
:disabled="!props.isShowDrag"
|
||||||
:list="form.list"
|
|
||||||
item-key="dateIndex"
|
|
||||||
:force-fallback="true"
|
:force-fallback="true"
|
||||||
>
|
>
|
||||||
<template #item="{ element, index }">
|
<div
|
||||||
<div class="draggableElement gap-[8px] py-[6px] pr-[8px]" :class="[props.isShowDrag ? 'cursor-move' : '']">
|
v-for="(element, index) in form.list"
|
||||||
<div v-if="props.isShowDrag" class="ml-[8px] mr-[8px] pt-[8px]">
|
:key="`${element.filed}${index}`"
|
||||||
<MsIcon type="icon-icon_drag" class="block text-[16px] text-[var(--color-text-4)]"
|
class="draggableElement gap-[8px] py-[6px] pr-[8px]"
|
||||||
/></div>
|
:class="[props.isShowDrag ? 'cursor-move' : '']"
|
||||||
<a-form-item
|
>
|
||||||
v-for="model of props.models"
|
<div v-if="props.isShowDrag" class="ml-[8px] mr-[8px] pt-[8px]">
|
||||||
:key="`${model.filed}${index}`"
|
<MsIcon type="icon-icon_drag" class="block text-[16px] text-[var(--color-text-4)]"
|
||||||
:field="`list[${index}].${model.filed}`"
|
/></div>
|
||||||
:class="index > 0 ? 'hidden-item' : 'mb-0 flex-1'"
|
<a-form-item
|
||||||
:rules="
|
v-for="model of props.models"
|
||||||
model.rules?.map((e) => {
|
:key="`${model.filed}${index}`"
|
||||||
if (e.notRepeat === true) {
|
:field="`list[${index}].${model.filed}`"
|
||||||
return {
|
:class="index > 0 ? 'hidden-item' : 'mb-0 flex-1'"
|
||||||
validator: (val, callback) => fieldNotRepeat(val, callback, index, model.filed, e.message),
|
:rules="
|
||||||
};
|
model.rules?.map((e) => {
|
||||||
}
|
if (e.notRepeat === true) {
|
||||||
return e;
|
return {
|
||||||
})
|
validator: (val, callback) => fieldNotRepeat(val, callback, index, model.filed, e.message),
|
||||||
"
|
};
|
||||||
asterisk-position="end"
|
}
|
||||||
:hide-asterisk="model.hideAsterisk"
|
return e;
|
||||||
:hide-label="model.hideLabel"
|
})
|
||||||
:content-flex="model.type !== 'multiple'"
|
"
|
||||||
:merge-props="model.type !== 'multiple'"
|
asterisk-position="end"
|
||||||
>
|
:hide-asterisk="model.hideAsterisk"
|
||||||
<template #label>
|
:hide-label="model.hideLabel"
|
||||||
<div class="inline-flex flex-row">
|
:content-flex="model.type !== 'multiple'"
|
||||||
<div>{{ index === 0 && model.label ? t(model.label) : '' }}</div>
|
:merge-props="model.type !== 'multiple'"
|
||||||
<div v-if="model.hasRedStar" class="ml-[2px] flex items-center">
|
>
|
||||||
<svg-icon width="6px" height="6px" name="form-star" class="text-[rgb(var(--danger-6))]" />
|
<template #label>
|
||||||
</div>
|
<div class="inline-flex flex-row">
|
||||||
|
<div>{{ index === 0 && model.label ? t(model.label) : '' }}</div>
|
||||||
|
<div v-if="model.hasRedStar" class="ml-[2px] flex items-center">
|
||||||
|
<svg-icon width="6px" height="6px" name="form-star" class="text-[rgb(var(--danger-6))]" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<a-input
|
|
||||||
v-if="model.type === 'input'"
|
|
||||||
v-model="element[model.filed]"
|
|
||||||
class="flex-1"
|
|
||||||
:placeholder="t(model.placeholder || '')"
|
|
||||||
:max-length="model.maxLength || 250"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
<a-input-number
|
|
||||||
v-if="model.type === 'inputNumber'"
|
|
||||||
v-model="element[model.filed]"
|
|
||||||
class="flex-1"
|
|
||||||
:placeholder="t(model.placeholder || '')"
|
|
||||||
:min="model.min"
|
|
||||||
:max="model.max || 9999999"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
<MsTagsInput
|
|
||||||
v-if="model.type === 'tagInput'"
|
|
||||||
v-model:model-value="element[model.filed]"
|
|
||||||
class="flex-1"
|
|
||||||
:placeholder="t(model.placeholder || 'common.tagPlaceholder')"
|
|
||||||
allow-clear
|
|
||||||
unique-value
|
|
||||||
retain-input-value
|
|
||||||
:max-tag-count="2"
|
|
||||||
/>
|
|
||||||
<a-select
|
|
||||||
v-if="model.type === 'select'"
|
|
||||||
v-model="element[model.filed]"
|
|
||||||
class="flex-1"
|
|
||||||
:placeholder="t(model.placeholder || '')"
|
|
||||||
:options="model.options"
|
|
||||||
:field-names="model.filedNames"
|
|
||||||
/>
|
|
||||||
<div v-if="model.type === 'multiple'" class="flex flex-row gap-[4px]">
|
|
||||||
<a-form-item
|
|
||||||
v-for="(child, childIndex) in model.children"
|
|
||||||
:key="`${child.filed}${childIndex}${index}`"
|
|
||||||
:field="`list[${index}].${child.filed}`"
|
|
||||||
:label="child.label ? t(child.label) : ''"
|
|
||||||
asterisk-position="end"
|
|
||||||
:hide-asterisk="child.hideAsterisk"
|
|
||||||
:hide-label="child.hideLabel"
|
|
||||||
class="hidden-item"
|
|
||||||
:rules="child.rules"
|
|
||||||
>
|
|
||||||
<a-input
|
|
||||||
v-if="child.type === 'input'"
|
|
||||||
v-model="element[child.filed]"
|
|
||||||
:class="child.className"
|
|
||||||
:placeholder="t(child.placeholder || '')"
|
|
||||||
:max-length="child.maxLength || 250"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
<a-select
|
|
||||||
v-if="child.type === 'select'"
|
|
||||||
v-model="element[child.filed]"
|
|
||||||
:class="child.className"
|
|
||||||
:placeholder="t(child.placeholder || '')"
|
|
||||||
:options="child.options"
|
|
||||||
:field-names="child.filedNames"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</template>
|
||||||
<div v-if="showEnable">
|
<a-input
|
||||||
<a-switch
|
v-if="model.type === 'input'"
|
||||||
v-model="element.enable"
|
v-model="element[model.filed]"
|
||||||
class="mt-[8px]"
|
class="flex-1"
|
||||||
:style="{ 'margin-top': index === 0 && !props.isShowDrag ? '36px' : '' }"
|
:placeholder="t(model.placeholder || '')"
|
||||||
size="small"
|
:max-length="model.maxLength || 250"
|
||||||
/>
|
allow-clear
|
||||||
|
/>
|
||||||
|
<a-input-number
|
||||||
|
v-if="model.type === 'inputNumber'"
|
||||||
|
v-model="element[model.filed]"
|
||||||
|
class="flex-1"
|
||||||
|
:placeholder="t(model.placeholder || '')"
|
||||||
|
:min="model.min"
|
||||||
|
:max="model.max || 9999999"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
<MsTagsInput
|
||||||
|
v-if="model.type === 'tagInput'"
|
||||||
|
v-model:model-value="element[model.filed]"
|
||||||
|
class="flex-1"
|
||||||
|
:placeholder="t(model.placeholder || 'common.tagPlaceholder')"
|
||||||
|
allow-clear
|
||||||
|
unique-value
|
||||||
|
retain-input-value
|
||||||
|
:max-tag-count="2"
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-if="model.type === 'select'"
|
||||||
|
v-model="element[model.filed]"
|
||||||
|
class="flex-1"
|
||||||
|
:placeholder="t(model.placeholder || '')"
|
||||||
|
:options="model.options"
|
||||||
|
:field-names="model.filedNames"
|
||||||
|
/>
|
||||||
|
<div v-if="model.type === 'multiple'" class="flex flex-row gap-[4px]">
|
||||||
|
<a-form-item
|
||||||
|
v-for="(child, childIndex) in model.children"
|
||||||
|
:key="`${child.filed}${childIndex}${index}`"
|
||||||
|
:field="`list[${index}].${child.filed}`"
|
||||||
|
:label="child.label ? t(child.label) : ''"
|
||||||
|
asterisk-position="end"
|
||||||
|
:hide-asterisk="child.hideAsterisk"
|
||||||
|
:hide-label="child.hideLabel"
|
||||||
|
class="hidden-item"
|
||||||
|
:rules="child.rules"
|
||||||
|
>
|
||||||
|
<a-input
|
||||||
|
v-if="child.type === 'input'"
|
||||||
|
v-model="element[child.filed]"
|
||||||
|
:class="child.className"
|
||||||
|
:placeholder="t(child.placeholder || '')"
|
||||||
|
:max-length="child.maxLength || 250"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-if="child.type === 'select'"
|
||||||
|
v-model="element[child.filed]"
|
||||||
|
:class="child.className"
|
||||||
|
:placeholder="t(child.placeholder || '')"
|
||||||
|
:options="child.options"
|
||||||
|
:field-names="child.filedNames"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div
|
</a-form-item>
|
||||||
v-show="form.list.length > 1"
|
<div v-if="showEnable">
|
||||||
class="minus"
|
<a-switch
|
||||||
:class="[
|
v-model="element.enable"
|
||||||
'flex',
|
class="mt-[8px]"
|
||||||
'h-full',
|
|
||||||
'w-[32px]',
|
|
||||||
'cursor-pointer',
|
|
||||||
'items-center',
|
|
||||||
'justify-center',
|
|
||||||
'text-[var(--color-text-4)]',
|
|
||||||
'mt-[8px]',
|
|
||||||
]"
|
|
||||||
:style="{ 'margin-top': index === 0 && !props.isShowDrag ? '36px' : '' }"
|
:style="{ 'margin-top': index === 0 && !props.isShowDrag ? '36px' : '' }"
|
||||||
@click="removeField(index)"
|
size="small"
|
||||||
>
|
/>
|
||||||
<icon-minus-circle />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div
|
||||||
</Draggable>
|
v-show="form.list.length > 1"
|
||||||
|
class="minus"
|
||||||
|
:class="[
|
||||||
|
'flex',
|
||||||
|
'h-full',
|
||||||
|
'w-[32px]',
|
||||||
|
'cursor-pointer',
|
||||||
|
'items-center',
|
||||||
|
'justify-center',
|
||||||
|
'text-[var(--color-text-4)]',
|
||||||
|
'mt-[8px]',
|
||||||
|
]"
|
||||||
|
:style="{ 'margin-top': index === 0 && !props.isShowDrag ? '36px' : '' }"
|
||||||
|
@click="removeField(index)"
|
||||||
|
>
|
||||||
|
<icon-minus-circle />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VueDraggable>
|
||||||
</a-scrollbar>
|
</a-scrollbar>
|
||||||
<div v-if="props.formMode === 'create'" class="w-full">
|
<div v-if="props.formMode === 'create'" class="w-full">
|
||||||
<a-button class="px-0" type="text" @click="addField">
|
<a-button class="px-0" type="text" @click="addField">
|
||||||
|
@ -166,7 +167,7 @@
|
||||||
|
|
||||||
import type { FormItemModel, FormMode } from './types';
|
import type { FormItemModel, FormMode } from './types';
|
||||||
import type { FormInstance, ValidatedError } from '@arco-design/web-vue';
|
import type { FormInstance, ValidatedError } from '@arco-design/web-vue';
|
||||||
import Draggable from 'vuedraggable';
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
|
|
@ -67,17 +67,15 @@
|
||||||
t('msTable.columnSetting.nonSort')
|
t('msTable.columnSetting.nonSort')
|
||||||
}}</span></a-divider
|
}}</span></a-divider
|
||||||
>
|
>
|
||||||
<Draggable tag="div" :list="couldSortColumn" ghost-class="ghost" item-key="dateIndex" @change="handleDragChange">
|
<VueDraggable v-model="couldSortColumn" ghost-class="ghost">
|
||||||
<template #item="{ element }">
|
<div v-for="element in couldSortColumn" :key="element.dataIndex" class="column-drag-item">
|
||||||
<div class="column-drag-item">
|
<div class="flex w-[90%] items-center">
|
||||||
<div class="flex w-[90%] items-center">
|
<MsIcon type="icon-icon_drag" class="text-[16px] text-[var(--color-text-4)]" />
|
||||||
<MsIcon type="icon-icon_drag" class="text-[16px] text-[var(--color-text-4)]" />
|
<span class="ml-[8px]">{{ t(element.title as string) }}</span>
|
||||||
<span class="ml-[8px]">{{ t(element.title as string) }}</span>
|
|
||||||
</div>
|
|
||||||
<a-switch v-model="element.showInTable" size="small" @change="handleSwitchChange" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<a-switch v-model="element.showInTable" size="small" @update="handleSwitchChange" />
|
||||||
</Draggable>
|
</div>
|
||||||
|
</VueDraggable>
|
||||||
</div>
|
</div>
|
||||||
</MsDrawer>
|
</MsDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -95,7 +93,7 @@
|
||||||
import { TableOpenDetailMode } from '@/store/modules/components/ms-table/types';
|
import { TableOpenDetailMode } from '@/store/modules/components/ms-table/types';
|
||||||
|
|
||||||
import { MsTableColumn } from './type';
|
import { MsTableColumn } from './type';
|
||||||
import Draggable from 'vuedraggable';
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
|
|
||||||
const tableStore = useTableStore();
|
const tableStore = useTableStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
|
@ -71,24 +71,20 @@
|
||||||
<MsButton @click="clearHandler">{{ t('system.orgTemplate.clear') }}</MsButton>
|
<MsButton @click="clearHandler">{{ t('system.orgTemplate.clear') }}</MsButton>
|
||||||
</div>
|
</div>
|
||||||
<div class="selected-list p-4">
|
<div class="selected-list p-4">
|
||||||
<Draggable tag="div" :list="selectedList" ghost-class="ghost" item-key="dateIndex">
|
<VueDraggable v-model="selectedList" ghost-class="ghost">
|
||||||
<template #item="{ element }">
|
<div v-for="element in selectedList" :key="element.dateIndex" class="selected-item">
|
||||||
<div class="selected-item">
|
<a-tooltip :content="element.name">
|
||||||
<a-tooltip :content="element.name">
|
<span> <MsIcon type="icon-icon_drag" class="mt-[3px] text-[16px] text-[var(--color-text-4)]" /></span>
|
||||||
<span>
|
<span class="one-line-text ml-2 w-[270px]">{{ element.name }}</span>
|
||||||
<MsIcon type="icon-icon_drag" class="mt-[3px] text-[16px] text-[var(--color-text-4)]"
|
</a-tooltip>
|
||||||
/></span>
|
<icon-close
|
||||||
<span class="one-line-text ml-2 w-[270px]">{{ element.name }}</span>
|
v-if="!element.internal"
|
||||||
</a-tooltip>
|
:style="{ 'font-size': '14px' }"
|
||||||
<icon-close
|
class="cursor-pointer text-[var(--color-text-3)]"
|
||||||
v-if="!element.internal"
|
@click="removeSelectedField(element.id)"
|
||||||
:style="{ 'font-size': '14px' }"
|
/>
|
||||||
class="cursor-pointer text-[var(--color-text-3)]"
|
</div>
|
||||||
@click="removeSelectedField(element.id)"
|
</VueDraggable>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Draggable>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,7 +106,7 @@
|
||||||
|
|
||||||
import type { DefinedFieldItem } from '@/models/setting/template';
|
import type { DefinedFieldItem } from '@/models/setting/template';
|
||||||
|
|
||||||
import Draggable from 'vuedraggable';
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue