mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 20:28:45 +08:00 
			
		
		
		
	封装拖拽组件,提供移动、新增、删除功能
This commit is contained in:
		@@ -39,30 +39,9 @@
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
      </el-card>
 | 
			
		||||
      <el-card header="内容设置" class="property-group" shadow="never">
 | 
			
		||||
        <el-text type="info" size="small"> 拖动左上角的小圆点可对其排序 </el-text>
 | 
			
		||||
        <template v-if="formData.items[0]">
 | 
			
		||||
          <draggable
 | 
			
		||||
            :list="formData.items"
 | 
			
		||||
            :force-fallback="true"
 | 
			
		||||
            :animation="200"
 | 
			
		||||
            handle=".drag-icon"
 | 
			
		||||
            class="m-t-8px"
 | 
			
		||||
            item-key="index"
 | 
			
		||||
          >
 | 
			
		||||
            <template #item="{ element, index }">
 | 
			
		||||
              <div class="content mb-4px flex flex-col gap-4px rounded bg-gray-50 p-8px">
 | 
			
		||||
                <div
 | 
			
		||||
                  class="m--8px m-b-8px flex flex-row items-center justify-between bg-gray-100 p-8px"
 | 
			
		||||
                >
 | 
			
		||||
                  <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
                  <Icon
 | 
			
		||||
                    icon="ep:delete"
 | 
			
		||||
                    class="cursor-pointer text-red-5"
 | 
			
		||||
                    @click="handleDeleteImage(index)"
 | 
			
		||||
                    v-if="formData.items.length > 1"
 | 
			
		||||
                  />
 | 
			
		||||
                </div>
 | 
			
		||||
                <el-form-item label="类型" prop="type" class="m-b-8px!" label-width="50px">
 | 
			
		||||
        <Draggable v-model="formData.items" :empty-item="{ type: 'img' }">
 | 
			
		||||
          <template #default="{ element }">
 | 
			
		||||
            <el-form-item label="类型" prop="type" class="m-b-8px!" label-width="40px">
 | 
			
		||||
              <el-radio-group v-model="element.type">
 | 
			
		||||
                <el-radio label="img">图片</el-radio>
 | 
			
		||||
                <el-radio label="video">视频</el-radio>
 | 
			
		||||
@@ -71,7 +50,7 @@
 | 
			
		||||
            <el-form-item
 | 
			
		||||
              label="图片"
 | 
			
		||||
              class="m-b-8px!"
 | 
			
		||||
                  label-width="50px"
 | 
			
		||||
              label-width="40px"
 | 
			
		||||
              v-if="element.type === 'img'"
 | 
			
		||||
            >
 | 
			
		||||
              <UploadImg
 | 
			
		||||
@@ -83,7 +62,7 @@
 | 
			
		||||
              />
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
            <template v-else>
 | 
			
		||||
                  <el-form-item label="封面" class="m-b-8px!" label-width="50px">
 | 
			
		||||
              <el-form-item label="封面" class="m-b-8px!" label-width="40px">
 | 
			
		||||
                <UploadImg
 | 
			
		||||
                  v-model="element.imgUrl"
 | 
			
		||||
                  draggable="false"
 | 
			
		||||
@@ -92,7 +71,7 @@
 | 
			
		||||
                  class="min-w-80px"
 | 
			
		||||
                />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
                  <el-form-item label="视频" class="m-b-8px!" label-width="50px">
 | 
			
		||||
              <el-form-item label="视频" class="m-b-8px!" label-width="40px">
 | 
			
		||||
                <UploadFile
 | 
			
		||||
                  v-model="element.videoUrl"
 | 
			
		||||
                  :file-type="['mp4']"
 | 
			
		||||
@@ -102,24 +81,18 @@
 | 
			
		||||
                />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </template>
 | 
			
		||||
                <el-form-item label="链接" class="m-b-8px!" label-width="50px">
 | 
			
		||||
            <el-form-item label="链接" class="m-b-8px!" label-width="40px">
 | 
			
		||||
              <AppLinkInput v-model="element.url" />
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
              </div>
 | 
			
		||||
          </template>
 | 
			
		||||
          </draggable>
 | 
			
		||||
        </template>
 | 
			
		||||
        <el-button @click="handleAddImage" type="primary" plain class="w-full">
 | 
			
		||||
          添加图片
 | 
			
		||||
        </el-button>
 | 
			
		||||
        </Draggable>
 | 
			
		||||
      </el-card>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </ComponentContainerProperty>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import draggable from 'vuedraggable' //拖拽组件
 | 
			
		||||
import { CarouselItemProperty, CarouselProperty } from './config'
 | 
			
		||||
import { CarouselProperty } from './config'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
 | 
			
		||||
// 轮播图属性面板
 | 
			
		||||
@@ -128,15 +101,6 @@ defineOptions({ name: 'CarouselProperty' })
 | 
			
		||||
const props = defineProps<{ modelValue: CarouselProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
// 添加图片
 | 
			
		||||
const handleAddImage = () => {
 | 
			
		||||
  formData.value.items.push({} as CarouselItemProperty)
 | 
			
		||||
}
 | 
			
		||||
// 删除图片
 | 
			
		||||
const handleDeleteImage = (index: number) => {
 | 
			
		||||
  formData.value.items.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,23 +9,9 @@
 | 
			
		||||
        </el-radio-group>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
 | 
			
		||||
      <el-text tag="p"> 菜单设置 </el-text>
 | 
			
		||||
      <el-text type="info" size="small"> 拖动左侧的小圆点可以调整顺序 </el-text>
 | 
			
		||||
      <template v-if="formData.list.length">
 | 
			
		||||
        <VueDraggable
 | 
			
		||||
          class="m-t-8px"
 | 
			
		||||
          :list="formData.list"
 | 
			
		||||
          item-key="index"
 | 
			
		||||
          handle=".drag-icon"
 | 
			
		||||
          :forceFallback="true"
 | 
			
		||||
          :animation="200"
 | 
			
		||||
        >
 | 
			
		||||
          <template #item="{ element, index }">
 | 
			
		||||
            <div class="mb-4px flex flex-col gap-4px rounded bg-gray-100 p-8px">
 | 
			
		||||
              <div class="flex flex-row justify-between">
 | 
			
		||||
                <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
                <Icon icon="ep:delete" class="text-red-500" @click="handleDeleteMenu(index)" />
 | 
			
		||||
              </div>
 | 
			
		||||
      <el-card header="菜单设置" class="property-group" shadow="never">
 | 
			
		||||
        <Draggable v-model="formData.list" :empty-item="EMPTY_MENU_GRID_ITEM_PROPERTY">
 | 
			
		||||
          <template #default="{ element }">
 | 
			
		||||
            <el-form-item label="图标" prop="iconUrl">
 | 
			
		||||
              <UploadImg v-model="element.iconUrl" height="80px" width="80px">
 | 
			
		||||
                <template #tip> 建议尺寸:44 * 44 </template>
 | 
			
		||||
@@ -54,27 +40,19 @@
 | 
			
		||||
                <ColorInput v-model="element.badge.bgColor" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </template>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </VueDraggable>
 | 
			
		||||
      </template>
 | 
			
		||||
      <el-form-item label-width="0">
 | 
			
		||||
        <el-button @click="handleAddMenu" type="primary" plain class="m-t-8px w-full">
 | 
			
		||||
          <Icon icon="ep:plus" class="mr-5px" /> 添加菜单
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
        </Draggable>
 | 
			
		||||
      </el-card>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </ComponentContainerProperty>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import VueDraggable from 'vuedraggable'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
import {
 | 
			
		||||
  EMPTY_MENU_GRID_ITEM_PROPERTY,
 | 
			
		||||
  MenuGridProperty
 | 
			
		||||
} from '@/components/DiyEditor/components/mobile/MenuGrid/config'
 | 
			
		||||
import { cloneDeep } from 'lodash-es'
 | 
			
		||||
 | 
			
		||||
/** 宫格导航属性面板 */
 | 
			
		||||
defineOptions({ name: 'MenuGridProperty' })
 | 
			
		||||
@@ -82,15 +60,6 @@ defineOptions({ name: 'MenuGridProperty' })
 | 
			
		||||
const props = defineProps<{ modelValue: MenuGridProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
/* 添加菜单 */
 | 
			
		||||
const handleAddMenu = () => {
 | 
			
		||||
  formData.value.list.push(cloneDeep(EMPTY_MENU_GRID_ITEM_PROPERTY))
 | 
			
		||||
}
 | 
			
		||||
/* 删除菜单 */
 | 
			
		||||
const handleDeleteMenu = (index: number) => {
 | 
			
		||||
  formData.value.list.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -5,20 +5,8 @@
 | 
			
		||||
 | 
			
		||||
    <!-- 表单 -->
 | 
			
		||||
    <el-form label-width="60px" :model="formData" class="m-t-8px">
 | 
			
		||||
      <div v-if="formData.list.length">
 | 
			
		||||
        <VueDraggable
 | 
			
		||||
          :list="formData.list"
 | 
			
		||||
          item-key="index"
 | 
			
		||||
          handle=".drag-icon"
 | 
			
		||||
          :forceFallback="true"
 | 
			
		||||
          :animation="200"
 | 
			
		||||
        >
 | 
			
		||||
          <template #item="{ element, index }">
 | 
			
		||||
            <div class="mb-4px flex flex-col gap-4px rounded bg-gray-100 p-8px">
 | 
			
		||||
              <div class="flex flex-row justify-between">
 | 
			
		||||
                <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
                <Icon icon="ep:delete" class="text-red-500" @click="handleDeleteMenu(index)" />
 | 
			
		||||
              </div>
 | 
			
		||||
      <Draggable v-model="formData.list" :empty-item="EMPTY_MENU_LIST_ITEM_PROPERTY">
 | 
			
		||||
        <template #default="{ element }">
 | 
			
		||||
          <el-form-item label="图标" prop="iconUrl">
 | 
			
		||||
            <UploadImg v-model="element.iconUrl" height="80px" width="80px">
 | 
			
		||||
              <template #tip> 建议尺寸:44 * 44 </template>
 | 
			
		||||
@@ -33,27 +21,18 @@
 | 
			
		||||
          <el-form-item label="链接" prop="url">
 | 
			
		||||
            <AppLinkInput v-model="element.url" />
 | 
			
		||||
          </el-form-item>
 | 
			
		||||
            </div>
 | 
			
		||||
        </template>
 | 
			
		||||
        </VueDraggable>
 | 
			
		||||
      </div>
 | 
			
		||||
      <el-form-item label-width="0">
 | 
			
		||||
        <el-button @click="handleAddMenu" type="primary" plain class="m-t-8px w-full">
 | 
			
		||||
          <Icon icon="ep:plus" class="mr-5px" /> 添加菜单
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      </Draggable>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </ComponentContainerProperty>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import VueDraggable from 'vuedraggable'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
import {
 | 
			
		||||
  EMPTY_MENU_LIST_ITEM_PROPERTY,
 | 
			
		||||
  MenuListProperty
 | 
			
		||||
} from '@/components/DiyEditor/components/mobile/MenuList/config'
 | 
			
		||||
import { cloneDeep } from 'lodash-es'
 | 
			
		||||
 | 
			
		||||
/** 列表导航属性面板 */
 | 
			
		||||
defineOptions({ name: 'MenuListProperty' })
 | 
			
		||||
@@ -61,15 +40,6 @@ defineOptions({ name: 'MenuListProperty' })
 | 
			
		||||
const props = defineProps<{ modelValue: MenuListProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
/* 添加菜单 */
 | 
			
		||||
const handleAddMenu = () => {
 | 
			
		||||
  formData.value.list.push(cloneDeep(EMPTY_MENU_LIST_ITEM_PROPERTY))
 | 
			
		||||
}
 | 
			
		||||
/* 删除菜单 */
 | 
			
		||||
const handleDeleteMenu = (index: number) => {
 | 
			
		||||
  formData.value.list.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -22,23 +22,9 @@
 | 
			
		||||
        </el-radio-group>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
 | 
			
		||||
      <el-text tag="p"> 菜单设置 </el-text>
 | 
			
		||||
      <el-text type="info" size="small"> 拖动左侧的小圆点可以调整顺序 </el-text>
 | 
			
		||||
      <template v-if="formData.list.length">
 | 
			
		||||
        <VueDraggable
 | 
			
		||||
          class="m-t-8px"
 | 
			
		||||
          :list="formData.list"
 | 
			
		||||
          item-key="index"
 | 
			
		||||
          handle=".drag-icon"
 | 
			
		||||
          :forceFallback="true"
 | 
			
		||||
          :animation="200"
 | 
			
		||||
        >
 | 
			
		||||
          <template #item="{ element, index }">
 | 
			
		||||
            <div class="mb-4px flex flex-col gap-4px rounded bg-gray-100 p-8px">
 | 
			
		||||
              <div class="flex flex-row justify-between">
 | 
			
		||||
                <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
                <Icon icon="ep:delete" class="text-red-500" @click="handleDeleteMenu(index)" />
 | 
			
		||||
              </div>
 | 
			
		||||
      <el-card header="菜单设置" class="property-group" shadow="never">
 | 
			
		||||
        <Draggable v-model="formData.list" :empty-item="cloneDeep(EMPTY_MENU_SWIPER_ITEM_PROPERTY">
 | 
			
		||||
          <template #default="{ element }">
 | 
			
		||||
            <el-form-item label="图标" prop="iconUrl">
 | 
			
		||||
              <UploadImg v-model="element.iconUrl" height="80px" width="80px">
 | 
			
		||||
                <template #tip> 建议尺寸:98 * 98 </template>
 | 
			
		||||
@@ -64,21 +50,14 @@
 | 
			
		||||
                <ColorInput v-model="element.badge.bgColor" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </template>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </VueDraggable>
 | 
			
		||||
      </template>
 | 
			
		||||
      <el-form-item label-width="0">
 | 
			
		||||
        <el-button @click="handleAddMenu" type="primary" plain class="m-t-8px w-full">
 | 
			
		||||
          <Icon icon="ep:plus" class="mr-5px" /> 添加菜单
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
        </Draggable>
 | 
			
		||||
      </el-card>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </ComponentContainerProperty>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import VueDraggable from 'vuedraggable'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
import {
 | 
			
		||||
  EMPTY_MENU_SWIPER_ITEM_PROPERTY,
 | 
			
		||||
@@ -92,15 +71,6 @@ defineOptions({ name: 'MenuSwiperProperty' })
 | 
			
		||||
const props = defineProps<{ modelValue: MenuSwiperProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
/* 添加菜单 */
 | 
			
		||||
const handleAddMenu = () => {
 | 
			
		||||
  formData.value.list.push(cloneDeep(EMPTY_MENU_SWIPER_ITEM_PROPERTY))
 | 
			
		||||
}
 | 
			
		||||
/* 删除菜单 */
 | 
			
		||||
const handleDeleteMenu = (index: number) => {
 | 
			
		||||
  formData.value.list.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { DiyComponent } from '@/components/DiyEditor/util'
 | 
			
		||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
 | 
			
		||||
 | 
			
		||||
/** 公告栏属性 */
 | 
			
		||||
export interface NoticeBarProperty {
 | 
			
		||||
@@ -10,6 +10,8 @@ export interface NoticeBarProperty {
 | 
			
		||||
  backgroundColor: string
 | 
			
		||||
  // 文字颜色
 | 
			
		||||
  textColor: string
 | 
			
		||||
  // 组件样式
 | 
			
		||||
  style: ComponentStyle
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 内容属性 */
 | 
			
		||||
@@ -34,6 +36,11 @@ export const component = {
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    backgroundColor: '#fff',
 | 
			
		||||
    textColor: '#333'
 | 
			
		||||
    textColor: '#333',
 | 
			
		||||
    style: {
 | 
			
		||||
      bgType: 'color',
 | 
			
		||||
      bgColor: '#fff',
 | 
			
		||||
      marginBottom: 8
 | 
			
		||||
    } as ComponentStyle
 | 
			
		||||
  }
 | 
			
		||||
} as DiyComponent<NoticeBarProperty>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ComponentContainerProperty v-model="formData.style">
 | 
			
		||||
    <el-form label-width="80px" :model="formData" :rules="rules">
 | 
			
		||||
      <el-form-item label="公告图标" prop="iconUrl">
 | 
			
		||||
        <UploadImg v-model="formData.iconUrl" height="48px">
 | 
			
		||||
@@ -11,48 +12,26 @@
 | 
			
		||||
      <el-form-item label="文字颜色" prop="文字颜色">
 | 
			
		||||
        <ColorInput v-model="formData.textColor" />
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
    <el-text tag="p"> 公告内容 </el-text>
 | 
			
		||||
    <el-text type="info" size="small"> 拖动左上角的小圆点可以调整热词顺序 </el-text>
 | 
			
		||||
    <template v-if="formData.contents.length">
 | 
			
		||||
      <VueDraggable
 | 
			
		||||
        :list="formData.contents"
 | 
			
		||||
        item-key="index"
 | 
			
		||||
        handle=".drag-icon"
 | 
			
		||||
        :forceFallback="true"
 | 
			
		||||
        :animation="200"
 | 
			
		||||
        class="m-t-8px"
 | 
			
		||||
      >
 | 
			
		||||
        <template #item="{ element, index }">
 | 
			
		||||
          <div class="mb-4px flex flex-row gap-4px rounded bg-gray-100 p-8px">
 | 
			
		||||
            <div class="flex flex-col items-start justify-between">
 | 
			
		||||
              <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
              <Icon
 | 
			
		||||
                icon="ep:delete"
 | 
			
		||||
                class="cursor-pointer text-red-5"
 | 
			
		||||
                @click="handleDeleteContent(index)"
 | 
			
		||||
                v-if="formData.contents.length > 1"
 | 
			
		||||
              />
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="w-full flex flex-col gap-8px">
 | 
			
		||||
 | 
			
		||||
      <el-card header="公告内容" class="property-group" shadow="never">
 | 
			
		||||
        <Draggable v-model="formData.contents">
 | 
			
		||||
          <template #default="{ element }">
 | 
			
		||||
            <el-form-item label="公告" prop="text" label-width="40px">
 | 
			
		||||
              <el-input v-model="element.text" placeholder="请输入公告" />
 | 
			
		||||
              <AppLinkInput v-model="element.url" />
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </template>
 | 
			
		||||
      </VueDraggable>
 | 
			
		||||
    </template>
 | 
			
		||||
    <el-form-item label-width="0">
 | 
			
		||||
      <el-button @click="handleAddContent" type="primary" plain class="m-t-8px w-full">
 | 
			
		||||
        添加内容
 | 
			
		||||
      </el-button>
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
            <el-form-item label="链接" prop="url" label-width="40px">
 | 
			
		||||
              <AppLinkInput v-model="element.url" />
 | 
			
		||||
            </el-form-item>
 | 
			
		||||
          </template>
 | 
			
		||||
        </Draggable>
 | 
			
		||||
      </el-card>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </ComponentContainerProperty>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { NoticeBarProperty, NoticeContentProperty } from './config'
 | 
			
		||||
import { NoticeBarProperty } from './config'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
import VueDraggable from 'vuedraggable'
 | 
			
		||||
// 通知栏属性面板
 | 
			
		||||
defineOptions({ name: 'NoticeBarProperty' })
 | 
			
		||||
// 表单校验
 | 
			
		||||
@@ -63,15 +42,6 @@ const rules = {
 | 
			
		||||
const props = defineProps<{ modelValue: NoticeBarProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
/* 添加公告 */
 | 
			
		||||
const handleAddContent = () => {
 | 
			
		||||
  formData.value.contents.push({} as NoticeContentProperty)
 | 
			
		||||
}
 | 
			
		||||
/* 删除公告 */
 | 
			
		||||
const handleDeleteContent = (index: number) => {
 | 
			
		||||
  formData.value.contents.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,32 +1,15 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ComponentContainerProperty v-model="formData.style">
 | 
			
		||||
    <el-text tag="p"> 搜索热词 </el-text>
 | 
			
		||||
    <el-text type="info" size="small"> 拖动左侧的小圆点可以调整热词顺序 </el-text>
 | 
			
		||||
 | 
			
		||||
    <!-- 表单 -->
 | 
			
		||||
    <el-form label-width="80px" :model="formData" class="m-t-8px">
 | 
			
		||||
      <div v-if="formData.hotKeywords.length">
 | 
			
		||||
        <VueDraggable
 | 
			
		||||
          :list="formData.hotKeywords"
 | 
			
		||||
          item-key="index"
 | 
			
		||||
          handle=".drag-icon"
 | 
			
		||||
          :forceFallback="true"
 | 
			
		||||
          :animation="200"
 | 
			
		||||
        >
 | 
			
		||||
          <template #item="{ index }">
 | 
			
		||||
            <div class="mb-4px flex flex-row items-center gap-4px rounded bg-gray-100 p-8px">
 | 
			
		||||
              <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
      <el-card header="搜索热词" class="property-group" shadow="never">
 | 
			
		||||
        <Draggable v-model="formData.hotKeywords" :empty-item="''">
 | 
			
		||||
          <template #default="{ index }">
 | 
			
		||||
            <el-input v-model="formData.hotKeywords[index]" placeholder="请输入热词" />
 | 
			
		||||
              <Icon icon="ep:delete" class="text-red-500" @click="deleteHotWord(index)" />
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </VueDraggable>
 | 
			
		||||
      </div>
 | 
			
		||||
      <el-form-item label-width="0">
 | 
			
		||||
        <el-button @click="handleAddHotWord" type="primary" plain class="m-t-8px w-full">
 | 
			
		||||
          添加热词
 | 
			
		||||
        </el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
        </Draggable>
 | 
			
		||||
      </el-card>
 | 
			
		||||
      <el-card header="搜索样式" class="property-group" shadow="never">
 | 
			
		||||
        <el-form-item label="框体样式">
 | 
			
		||||
          <el-radio-group v-model="formData!.borderRadius">
 | 
			
		||||
            <el-tooltip content="方形" placement="top">
 | 
			
		||||
@@ -70,12 +53,12 @@
 | 
			
		||||
        <el-form-item class="lef" label="文本颜色" prop="textColor">
 | 
			
		||||
          <ColorInput v-model="formData.textColor" />
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
      </el-card>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </ComponentContainerProperty>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import VueDraggable from 'vuedraggable'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
import { SearchProperty } from '@/components/DiyEditor/components/mobile/SearchBar/config'
 | 
			
		||||
 | 
			
		||||
@@ -85,15 +68,6 @@ defineOptions({ name: 'SearchProperty' })
 | 
			
		||||
const props = defineProps<{ modelValue: SearchProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
/* 添加热词 */
 | 
			
		||||
const handleAddHotWord = () => {
 | 
			
		||||
  formData.value.hotKeywords.push('')
 | 
			
		||||
}
 | 
			
		||||
/* 删除热词 */
 | 
			
		||||
const deleteHotWord = (index: number) => {
 | 
			
		||||
  formData.value.hotKeywords.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,13 @@
 | 
			
		||||
      }"
 | 
			
		||||
    >
 | 
			
		||||
      <div v-for="(item, index) in property.items" :key="index" class="tab-bar-item">
 | 
			
		||||
        <img :src="index === 0 ? item.activeIconUrl : item.iconUrl" alt="" />
 | 
			
		||||
        <el-image :src="index === 0 ? item.activeIconUrl : item.iconUrl">
 | 
			
		||||
          <template #error>
 | 
			
		||||
            <div class="h-full w-full flex items-center justify-center">
 | 
			
		||||
              <Icon icon="ep:picture" />
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </el-image>
 | 
			
		||||
        <span :style="{ color: index === 0 ? property.style.activeColor : property.style.color }">
 | 
			
		||||
          {{ item.text }}
 | 
			
		||||
        </span>
 | 
			
		||||
@@ -48,7 +54,8 @@ defineProps<{ property: TabBarProperty }>()
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      justify-content: center;
 | 
			
		||||
 | 
			
		||||
      img {
 | 
			
		||||
      :deep(img),
 | 
			
		||||
      .el-icon {
 | 
			
		||||
        width: 26px;
 | 
			
		||||
        height: 26px;
 | 
			
		||||
        border-radius: 4px;
 | 
			
		||||
 
 | 
			
		||||
@@ -42,26 +42,8 @@
 | 
			
		||||
 | 
			
		||||
      <el-text tag="p">图标设置</el-text>
 | 
			
		||||
      <el-text type="info" size="small"> 拖动左上角的小圆点可对其排序, 图标建议尺寸 44*44 </el-text>
 | 
			
		||||
      <draggable
 | 
			
		||||
        :list="formData!.items"
 | 
			
		||||
        item-key="index"
 | 
			
		||||
        :forceFallback="true"
 | 
			
		||||
        :animation="200"
 | 
			
		||||
        handle=".drag-icon"
 | 
			
		||||
        class="m-t-8px"
 | 
			
		||||
      >
 | 
			
		||||
        <template #item="{ element, index }">
 | 
			
		||||
          <div class="mb-4px flex flex-row gap-4px rounded bg-gray-100 p-8px">
 | 
			
		||||
            <div class="flex flex-col items-start justify-between">
 | 
			
		||||
              <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
              <Icon
 | 
			
		||||
                icon="ep:delete"
 | 
			
		||||
                class="cursor-pointer text-red-5"
 | 
			
		||||
                @click="handleDeleteItem(index)"
 | 
			
		||||
                v-if="formData.items.length > 1"
 | 
			
		||||
              />
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="w-full flex flex-col">
 | 
			
		||||
      <Draggable v-model="formData.items" :limit="5">
 | 
			
		||||
        <template #default="{ element }">
 | 
			
		||||
          <div class="m-b-8px flex items-center justify-around">
 | 
			
		||||
            <div class="flex flex-col items-center justify-between">
 | 
			
		||||
              <UploadImg
 | 
			
		||||
@@ -71,7 +53,7 @@
 | 
			
		||||
                :show-delete="false"
 | 
			
		||||
                :show-btn-text="false"
 | 
			
		||||
              />
 | 
			
		||||
                  <el-text size="small">默认图片</el-text>
 | 
			
		||||
              <el-text size="small">未选中</el-text>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
              <UploadImg
 | 
			
		||||
@@ -81,41 +63,23 @@
 | 
			
		||||
                :show-delete="false"
 | 
			
		||||
                :show-btn-text="false"
 | 
			
		||||
              />
 | 
			
		||||
                  <el-text>选中图片</el-text>
 | 
			
		||||
              <el-text>已选中</el-text>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
              <el-form-item prop="text" label-width="0" class="m-b-8px!">
 | 
			
		||||
          <el-form-item prop="text" label="文字" label-width="48px" class="m-b-8px!">
 | 
			
		||||
            <el-input v-model="element.text" placeholder="请输入文字" />
 | 
			
		||||
          </el-form-item>
 | 
			
		||||
              <el-form-item prop="url" label-width="0" class="m-b-0!">
 | 
			
		||||
          <el-form-item prop="url" label="链接" label-width="48px" class="m-b-0!">
 | 
			
		||||
            <AppLinkInput v-model="element.url" />
 | 
			
		||||
          </el-form-item>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </template>
 | 
			
		||||
      </draggable>
 | 
			
		||||
 | 
			
		||||
      <el-form-item label-width="0">
 | 
			
		||||
        <!-- 添加导航按钮 -->
 | 
			
		||||
        <el-tooltip content="最多添加5个">
 | 
			
		||||
          <el-button
 | 
			
		||||
            @click="handleAddItem"
 | 
			
		||||
            class="m-b-16px w-full"
 | 
			
		||||
            type="primary"
 | 
			
		||||
            plain
 | 
			
		||||
            :disabled="formData!.items.length >= 5"
 | 
			
		||||
          >
 | 
			
		||||
            添加导航
 | 
			
		||||
          </el-button>
 | 
			
		||||
        </el-tooltip>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
      </Draggable>
 | 
			
		||||
    </el-form>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import draggable from 'vuedraggable' //拖拽组件
 | 
			
		||||
import { TabBarItemProperty, TabBarProperty, THEME_LIST } from './config'
 | 
			
		||||
import { TabBarProperty, THEME_LIST } from './config'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
// 底部导航栏
 | 
			
		||||
defineOptions({ name: 'TabBarProperty' })
 | 
			
		||||
@@ -124,15 +88,6 @@ const props = defineProps<{ modelValue: TabBarProperty }>()
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
/** 添加导航项 */
 | 
			
		||||
const handleAddItem = () => {
 | 
			
		||||
  formData?.value?.items?.push({} as TabBarItemProperty)
 | 
			
		||||
}
 | 
			
		||||
/** 删除导航项 */
 | 
			
		||||
const handleDeleteItem = (index: number) => {
 | 
			
		||||
  formData?.value?.items?.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 要的主题
 | 
			
		||||
const handleThemeChange = () => {
 | 
			
		||||
  const theme = THEME_LIST.find((theme) => theme.id === formData.value.theme)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										77
									
								
								src/components/Draggable/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/components/Draggable/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <el-text type="info" size="small"> 拖动左上角的小圆点可对其排序 </el-text>
 | 
			
		||||
  <VueDraggable
 | 
			
		||||
    :list="formData"
 | 
			
		||||
    :force-fallback="true"
 | 
			
		||||
    :animation="200"
 | 
			
		||||
    handle=".drag-icon"
 | 
			
		||||
    class="m-t-8px"
 | 
			
		||||
    item-key="index"
 | 
			
		||||
  >
 | 
			
		||||
    <template #item="{ element, index }">
 | 
			
		||||
      <div
 | 
			
		||||
        class="mb-4px flex flex-col gap-4px border border-gray-2 border-rounded rounded border-solid p-8px"
 | 
			
		||||
      >
 | 
			
		||||
        <!-- 操作按钮区 -->
 | 
			
		||||
        <div class="m--8px m-b-4px flex flex-row items-center justify-between bg-gray-1 p-8px">
 | 
			
		||||
          <el-tooltip content="拖动排序">
 | 
			
		||||
            <Icon icon="ic:round-drag-indicator" class="drag-icon cursor-move" />
 | 
			
		||||
          </el-tooltip>
 | 
			
		||||
          <el-tooltip content="删除">
 | 
			
		||||
            <Icon
 | 
			
		||||
              icon="ep:delete"
 | 
			
		||||
              class="cursor-pointer text-red-5"
 | 
			
		||||
              v-if="formData.length > 1"
 | 
			
		||||
              @click="handleDelete(index)"
 | 
			
		||||
            />
 | 
			
		||||
          </el-tooltip>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- 内容区 -->
 | 
			
		||||
        <slot :element="element" :index="index"></slot>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
  </VueDraggable>
 | 
			
		||||
  <el-tooltip :disabled="limit < 1" :content="`最多添加${limit}个`">
 | 
			
		||||
    <el-button
 | 
			
		||||
      type="primary"
 | 
			
		||||
      plain
 | 
			
		||||
      class="m-t-4px w-full"
 | 
			
		||||
      :disabled="limit > 0 && formData.length >= limit"
 | 
			
		||||
      @click="handleAdd"
 | 
			
		||||
    >
 | 
			
		||||
      <Icon icon="ep:plus" /><span>添加</span>
 | 
			
		||||
    </el-button>
 | 
			
		||||
  </el-tooltip>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
// 拖拽组件
 | 
			
		||||
import VueDraggable from 'vuedraggable'
 | 
			
		||||
import { usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
import { any, array } from 'vue-types'
 | 
			
		||||
import { propTypes } from '@/utils/propTypes'
 | 
			
		||||
import { cloneDeep } from 'lodash-es'
 | 
			
		||||
 | 
			
		||||
// 拖拽组件封装
 | 
			
		||||
defineOptions({ name: 'Draggable' })
 | 
			
		||||
 | 
			
		||||
// 定义属性
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  // 绑定值
 | 
			
		||||
  modelValue: array<any>().isRequired,
 | 
			
		||||
  // 空的元素:点击添加按钮时,创建元素并添加到列表;默认为空对象
 | 
			
		||||
  emptyItem: any<unknown>().def({}),
 | 
			
		||||
  // 数量限制:默认为0,表示不限制
 | 
			
		||||
  limit: propTypes.number.def(0)
 | 
			
		||||
})
 | 
			
		||||
// 定义事件
 | 
			
		||||
const emit = defineEmits(['update:modelValue'])
 | 
			
		||||
const { formData } = usePropertyForm(props.modelValue, emit)
 | 
			
		||||
 | 
			
		||||
// 处理添加
 | 
			
		||||
const handleAdd = () => formData.value.push(cloneDeep(props.emptyItem || {}))
 | 
			
		||||
// 处理删除
 | 
			
		||||
const handleDelete = (index: number) => formData.value.splice(index, 1)
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user