Skip to content

Commit 59ff6b1

Browse files
committed
封装拖拽组件,提供移动、新增、删除功能
1 parent 9ff4f1f commit 59ff6b1

File tree

10 files changed

+325
-462
lines changed

10 files changed

+325
-462
lines changed

src/components/DiyEditor/components/mobile/Carousel/property.vue

Lines changed: 47 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -39,87 +39,60 @@
3939
</el-form-item>
4040
</el-card>
4141
<el-card header="内容设置" class="property-group" shadow="never">
42-
<el-text type="info" size="small"> 拖动左上角的小圆点可对其排序 </el-text>
43-
<template v-if="formData.items[0]">
44-
<draggable
45-
:list="formData.items"
46-
:force-fallback="true"
47-
:animation="200"
48-
handle=".drag-icon"
49-
class="m-t-8px"
50-
item-key="index"
51-
>
52-
<template #item="{ element, index }">
53-
<div class="content mb-4px flex flex-col gap-4px rounded bg-gray-50 p-8px">
54-
<div
55-
class="m--8px m-b-8px flex flex-row items-center justify-between bg-gray-100 p-8px"
56-
>
57-
<Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
58-
<Icon
59-
icon="ep:delete"
60-
class="cursor-pointer text-red-5"
61-
@click="handleDeleteImage(index)"
62-
v-if="formData.items.length > 1"
63-
/>
64-
</div>
65-
<el-form-item label="类型" prop="type" class="m-b-8px!" label-width="50px">
66-
<el-radio-group v-model="element.type">
67-
<el-radio label="img">图片</el-radio>
68-
<el-radio label="video">视频</el-radio>
69-
</el-radio-group>
70-
</el-form-item>
71-
<el-form-item
72-
label="图片"
73-
class="m-b-8px!"
74-
label-width="50px"
75-
v-if="element.type === 'img'"
76-
>
77-
<UploadImg
78-
v-model="element.imgUrl"
79-
draggable="false"
80-
height="80px"
81-
width="100%"
82-
class="min-w-80px"
83-
/>
84-
</el-form-item>
85-
<template v-else>
86-
<el-form-item label="封面" class="m-b-8px!" label-width="50px">
87-
<UploadImg
88-
v-model="element.imgUrl"
89-
draggable="false"
90-
height="80px"
91-
width="100%"
92-
class="min-w-80px"
93-
/>
94-
</el-form-item>
95-
<el-form-item label="视频" class="m-b-8px!" label-width="50px">
96-
<UploadFile
97-
v-model="element.videoUrl"
98-
:file-type="['mp4']"
99-
:limit="1"
100-
:file-size="100"
101-
class="min-w-80px"
102-
/>
103-
</el-form-item>
104-
</template>
105-
<el-form-item label="链接" class="m-b-8px!" label-width="50px">
106-
<AppLinkInput v-model="element.url" />
107-
</el-form-item>
108-
</div>
42+
<Draggable v-model="formData.items" :empty-item="{ type: 'img' }">
43+
<template #default="{ element }">
44+
<el-form-item label="类型" prop="type" class="m-b-8px!" label-width="40px">
45+
<el-radio-group v-model="element.type">
46+
<el-radio label="img">图片</el-radio>
47+
<el-radio label="video">视频</el-radio>
48+
</el-radio-group>
49+
</el-form-item>
50+
<el-form-item
51+
label="图片"
52+
class="m-b-8px!"
53+
label-width="40px"
54+
v-if="element.type === 'img'"
55+
>
56+
<UploadImg
57+
v-model="element.imgUrl"
58+
draggable="false"
59+
height="80px"
60+
width="100%"
61+
class="min-w-80px"
62+
/>
63+
</el-form-item>
64+
<template v-else>
65+
<el-form-item label="封面" class="m-b-8px!" label-width="40px">
66+
<UploadImg
67+
v-model="element.imgUrl"
68+
draggable="false"
69+
height="80px"
70+
width="100%"
71+
class="min-w-80px"
72+
/>
73+
</el-form-item>
74+
<el-form-item label="视频" class="m-b-8px!" label-width="40px">
75+
<UploadFile
76+
v-model="element.videoUrl"
77+
:file-type="['mp4']"
78+
:limit="1"
79+
:file-size="100"
80+
class="min-w-80px"
81+
/>
82+
</el-form-item>
10983
</template>
110-
</draggable>
111-
</template>
112-
<el-button @click="handleAddImage" type="primary" plain class="w-full">
113-
添加图片
114-
</el-button>
84+
<el-form-item label="链接" class="m-b-8px!" label-width="40px">
85+
<AppLinkInput v-model="element.url" />
86+
</el-form-item>
87+
</template>
88+
</Draggable>
11589
</el-card>
11690
</el-form>
11791
</ComponentContainerProperty>
11892
</template>
11993

12094
<script setup lang="ts">
121-
import draggable from 'vuedraggable' //拖拽组件
122-
import { CarouselItemProperty, CarouselProperty } from './config'
95+
import { CarouselProperty } from './config'
12396
import { usePropertyForm } from '@/components/DiyEditor/util'
12497
12598
// 轮播图属性面板
@@ -128,15 +101,6 @@ defineOptions({ name: 'CarouselProperty' })
128101
const props = defineProps<{ modelValue: CarouselProperty }>()
129102
const emit = defineEmits(['update:modelValue'])
130103
const { formData } = usePropertyForm(props.modelValue, emit)
131-
132-
// 添加图片
133-
const handleAddImage = () => {
134-
formData.value.items.push({} as CarouselItemProperty)
135-
}
136-
// 删除图片
137-
const handleDeleteImage = (index: number) => {
138-
formData.value.items.splice(index, 1)
139-
}
140104
</script>
141105

142106
<style scoped lang="scss"></style>

src/components/DiyEditor/components/mobile/MenuGrid/property.vue

Lines changed: 31 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,88 +9,57 @@
99
</el-radio-group>
1010
</el-form-item>
1111

12-
<el-text tag="p"> 菜单设置 </el-text>
13-
<el-text type="info" size="small"> 拖动左侧的小圆点可以调整顺序 </el-text>
14-
<template v-if="formData.list.length">
15-
<VueDraggable
16-
class="m-t-8px"
17-
:list="formData.list"
18-
item-key="index"
19-
handle=".drag-icon"
20-
:forceFallback="true"
21-
:animation="200"
22-
>
23-
<template #item="{ element, index }">
24-
<div class="mb-4px flex flex-col gap-4px rounded bg-gray-100 p-8px">
25-
<div class="flex flex-row justify-between">
26-
<Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
27-
<Icon icon="ep:delete" class="text-red-500" @click="handleDeleteMenu(index)" />
28-
</div>
29-
<el-form-item label="图标" prop="iconUrl">
30-
<UploadImg v-model="element.iconUrl" height="80px" width="80px">
31-
<template #tip> 建议尺寸:44 * 44 </template>
32-
</UploadImg>
12+
<el-card header="菜单设置" class="property-group" shadow="never">
13+
<Draggable v-model="formData.list" :empty-item="EMPTY_MENU_GRID_ITEM_PROPERTY">
14+
<template #default="{ element }">
15+
<el-form-item label="图标" prop="iconUrl">
16+
<UploadImg v-model="element.iconUrl" height="80px" width="80px">
17+
<template #tip> 建议尺寸:44 * 44 </template>
18+
</UploadImg>
19+
</el-form-item>
20+
<el-form-item label="标题" prop="title">
21+
<InputWithColor v-model="element.title" v-model:color="element.titleColor" />
22+
</el-form-item>
23+
<el-form-item label="副标题" prop="subtitle">
24+
<InputWithColor v-model="element.subtitle" v-model:color="element.subtitleColor" />
25+
</el-form-item>
26+
<el-form-item label="链接" prop="url">
27+
<AppLinkInput v-model="element.url" />
28+
</el-form-item>
29+
<el-form-item label="显示角标" prop="badge.show">
30+
<el-switch v-model="element.badge.show" />
31+
</el-form-item>
32+
<template v-if="element.badge.show">
33+
<el-form-item label="角标内容" prop="badge.text">
34+
<InputWithColor
35+
v-model="element.badge.text"
36+
v-model:color="element.badge.textColor"
37+
/>
3338
</el-form-item>
34-
<el-form-item label="标题" prop="title">
35-
<InputWithColor v-model="element.title" v-model:color="element.titleColor" />
39+
<el-form-item label="背景颜色" prop="badge.bgColor">
40+
<ColorInput v-model="element.badge.bgColor" />
3641
</el-form-item>
37-
<el-form-item label="副标题" prop="subtitle">
38-
<InputWithColor v-model="element.subtitle" v-model:color="element.subtitleColor" />
39-
</el-form-item>
40-
<el-form-item label="链接" prop="url">
41-
<AppLinkInput v-model="element.url" />
42-
</el-form-item>
43-
<el-form-item label="显示角标" prop="badge.show">
44-
<el-switch v-model="element.badge.show" />
45-
</el-form-item>
46-
<template v-if="element.badge.show">
47-
<el-form-item label="角标内容" prop="badge.text">
48-
<InputWithColor
49-
v-model="element.badge.text"
50-
v-model:color="element.badge.textColor"
51-
/>
52-
</el-form-item>
53-
<el-form-item label="背景颜色" prop="badge.bgColor">
54-
<ColorInput v-model="element.badge.bgColor" />
55-
</el-form-item>
56-
</template>
57-
</div>
42+
</template>
5843
</template>
59-
</VueDraggable>
60-
</template>
61-
<el-form-item label-width="0">
62-
<el-button @click="handleAddMenu" type="primary" plain class="m-t-8px w-full">
63-
<Icon icon="ep:plus" class="mr-5px" /> 添加菜单
64-
</el-button>
65-
</el-form-item>
44+
</Draggable>
45+
</el-card>
6646
</el-form>
6747
</ComponentContainerProperty>
6848
</template>
6949

7050
<script setup lang="ts">
71-
import VueDraggable from 'vuedraggable'
7251
import { usePropertyForm } from '@/components/DiyEditor/util'
7352
import {
7453
EMPTY_MENU_GRID_ITEM_PROPERTY,
7554
MenuGridProperty
7655
} from '@/components/DiyEditor/components/mobile/MenuGrid/config'
77-
import { cloneDeep } from 'lodash-es'
7856
7957
/** 宫格导航属性面板 */
8058
defineOptions({ name: 'MenuGridProperty' })
8159
8260
const props = defineProps<{ modelValue: MenuGridProperty }>()
8361
const emit = defineEmits(['update:modelValue'])
8462
const { formData } = usePropertyForm(props.modelValue, emit)
85-
86-
/* 添加菜单 */
87-
const handleAddMenu = () => {
88-
formData.value.list.push(cloneDeep(EMPTY_MENU_GRID_ITEM_PROPERTY))
89-
}
90-
/* 删除菜单 */
91-
const handleDeleteMenu = (index: number) => {
92-
formData.value.list.splice(index, 1)
93-
}
9463
</script>
9564

9665
<style scoped lang="scss"></style>

src/components/DiyEditor/components/mobile/MenuList/property.vue

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,71 +5,41 @@
55

66
<!-- 表单 -->
77
<el-form label-width="60px" :model="formData" class="m-t-8px">
8-
<div v-if="formData.list.length">
9-
<VueDraggable
10-
:list="formData.list"
11-
item-key="index"
12-
handle=".drag-icon"
13-
:forceFallback="true"
14-
:animation="200"
15-
>
16-
<template #item="{ element, index }">
17-
<div class="mb-4px flex flex-col gap-4px rounded bg-gray-100 p-8px">
18-
<div class="flex flex-row justify-between">
19-
<Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
20-
<Icon icon="ep:delete" class="text-red-500" @click="handleDeleteMenu(index)" />
21-
</div>
22-
<el-form-item label="图标" prop="iconUrl">
23-
<UploadImg v-model="element.iconUrl" height="80px" width="80px">
24-
<template #tip> 建议尺寸:44 * 44 </template>
25-
</UploadImg>
26-
</el-form-item>
27-
<el-form-item label="标题" prop="title">
28-
<InputWithColor v-model="element.title" v-model:color="element.titleColor" />
29-
</el-form-item>
30-
<el-form-item label="副标题" prop="subtitle">
31-
<InputWithColor v-model="element.subtitle" v-model:color="element.subtitleColor" />
32-
</el-form-item>
33-
<el-form-item label="链接" prop="url">
34-
<AppLinkInput v-model="element.url" />
35-
</el-form-item>
36-
</div>
37-
</template>
38-
</VueDraggable>
39-
</div>
40-
<el-form-item label-width="0">
41-
<el-button @click="handleAddMenu" type="primary" plain class="m-t-8px w-full">
42-
<Icon icon="ep:plus" class="mr-5px" /> 添加菜单
43-
</el-button>
44-
</el-form-item>
8+
<Draggable v-model="formData.list" :empty-item="EMPTY_MENU_LIST_ITEM_PROPERTY">
9+
<template #default="{ element }">
10+
<el-form-item label="图标" prop="iconUrl">
11+
<UploadImg v-model="element.iconUrl" height="80px" width="80px">
12+
<template #tip> 建议尺寸:44 * 44 </template>
13+
</UploadImg>
14+
</el-form-item>
15+
<el-form-item label="标题" prop="title">
16+
<InputWithColor v-model="element.title" v-model:color="element.titleColor" />
17+
</el-form-item>
18+
<el-form-item label="副标题" prop="subtitle">
19+
<InputWithColor v-model="element.subtitle" v-model:color="element.subtitleColor" />
20+
</el-form-item>
21+
<el-form-item label="链接" prop="url">
22+
<AppLinkInput v-model="element.url" />
23+
</el-form-item>
24+
</template>
25+
</Draggable>
4526
</el-form>
4627
</ComponentContainerProperty>
4728
</template>
4829

4930
<script setup lang="ts">
50-
import VueDraggable from 'vuedraggable'
5131
import { usePropertyForm } from '@/components/DiyEditor/util'
5232
import {
5333
EMPTY_MENU_LIST_ITEM_PROPERTY,
5434
MenuListProperty
5535
} from '@/components/DiyEditor/components/mobile/MenuList/config'
56-
import { cloneDeep } from 'lodash-es'
5736
5837
/** 列表导航属性面板 */
5938
defineOptions({ name: 'MenuListProperty' })
6039
6140
const props = defineProps<{ modelValue: MenuListProperty }>()
6241
const emit = defineEmits(['update:modelValue'])
6342
const { formData } = usePropertyForm(props.modelValue, emit)
64-
65-
/* 添加菜单 */
66-
const handleAddMenu = () => {
67-
formData.value.list.push(cloneDeep(EMPTY_MENU_LIST_ITEM_PROPERTY))
68-
}
69-
/* 删除菜单 */
70-
const handleDeleteMenu = (index: number) => {
71-
formData.value.list.splice(index, 1)
72-
}
7343
</script>
7444

7545
<style scoped lang="scss"></style>

0 commit comments

Comments
 (0)