refactor: 拖动插件更换为vue-draggable-plus

This commit is contained in:
RubyLiu 2023-11-24 14:09:01 +08:00 committed by Craftsman
parent e89049ec76
commit 0b4e30e651
4 changed files with 156 additions and 161 deletions

View File

@ -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",

View File

@ -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();

View File

@ -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();

View File

@ -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();