feat:【mall】diy editor 的 menu-swiper 优化

pull/244/MERGE
YunaiV 2025-11-01 08:47:47 +08:00
parent 27b35ac0cf
commit 12968a3d66
3 changed files with 35 additions and 55 deletions

View File

@ -4,40 +4,28 @@ import { cloneDeep } from '@vben/utils';
/** 菜单导航属性 */
export interface MenuSwiperProperty {
// 布局: 图标+文字 | 图标
layout: 'icon' | 'iconText';
// 行数
row: number;
// 列数
column: number;
// 导航菜单列表
list: MenuSwiperItemProperty[];
// 组件样式
style: ComponentStyle;
}
/** 菜单导航项目属性 */
export interface MenuSwiperItemProperty {
// 图标链接
iconUrl: string;
// 标题
title: string;
// 标题颜色
titleColor: string;
// 链接
url: string;
// 角标
badge: {
// 角标背景颜色
bgColor: string;
// 是否显示
show: boolean;
// 角标文字
text: string;
// 角标文字颜色
textColor: string;
};
layout: 'icon' | 'iconText'; // 布局:图标+文字 | 图标
row: number; // 行数
column: number; // 列数
list: MenuSwiperItemProperty[]; // 导航菜单列表
style: ComponentStyle; // 组件样式
}
/** 菜单导航项目属性 */
export interface MenuSwiperItemProperty {
iconUrl: string; // 图标链接
title: string; // 标题
titleColor: string; // 标题颜色
url: string; // 链接
badge: {
bgColor: string; // 角标背景颜色
show: boolean; // 是否显示
text: string; // 角标文字
textColor: string; // 角标文字颜色
}; // 角标
}
/** 空菜单导航项目属性 */
export const EMPTY_MENU_SWIPER_ITEM_PROPERTY = {
title: '标题',
titleColor: '#333',
@ -48,7 +36,7 @@ export const EMPTY_MENU_SWIPER_ITEM_PROPERTY = {
},
} as MenuSwiperItemProperty;
// 定义组件
/** 定义组件 */
export const component = {
id: 'MenuSwiper',
name: '菜单导航',

View File

@ -7,22 +7,19 @@ import { ElCarousel, ElCarouselItem, ElImage } from 'element-plus';
/** 菜单导航 */
defineOptions({ name: 'MenuSwiper' });
const props = defineProps<{ property: MenuSwiperProperty }>();
//
const TITLE_HEIGHT = 20;
//
const ICON_SIZE = 32;
//
const SPACE_Y = 16;
//
const pages = ref<MenuSwiperItemProperty[][]>([]);
//
const carouselHeight = ref(0);
//
const rowHeight = ref(0);
//
const columnWidth = ref('');
const props = defineProps<{ property: MenuSwiperProperty }>();
const TITLE_HEIGHT = 20; //
const ICON_SIZE = 32; //
const SPACE_Y = 16; //
const pages = ref<MenuSwiperItemProperty[][]>([]); //
const carouselHeight = ref(0); //
const rowHeight = ref(0); //
const columnWidth = ref(''); //
watch(
() => props.property,
() => {
@ -75,9 +72,7 @@ watch(
class="relative flex flex-col items-center justify-center"
:style="{ width: columnWidth, height: `${rowHeight}px` }"
>
<!-- 图标 + 角标 -->
<div class="relative" :class="`h-${ICON_SIZE}px w-${ICON_SIZE}px`">
<!-- 右上角角标 -->
<span
v-if="item.badge?.show"
class="absolute -right-2.5 -top-2.5 z-10 h-5 rounded-[10px] px-1.5 text-center text-xs leading-5"
@ -94,7 +89,6 @@ watch(
class="h-full w-full"
/>
</div>
<!-- 标题 -->
<span
v-if="property.layout === 'iconText'"
class="text-xs"

View File

@ -28,13 +28,14 @@ import { EMPTY_MENU_SWIPER_ITEM_PROPERTY } from './config';
defineOptions({ name: 'MenuSwiperProperty' });
const props = defineProps<{ modelValue: MenuSwiperProperty }>();
const emit = defineEmits(['update:modelValue']);
const formData = useVModel(props, 'modelValue', emit);
</script>
<template>
<ComponentContainerProperty v-model="formData.style">
<!-- 表单 -->
<ElForm label-width="80px" :model="formData" class="mt-2">
<ElFormItem label="布局" prop="layout">
<ElRadioGroup v-model="formData.layout">
@ -55,7 +56,6 @@ const formData = useVModel(props, 'modelValue', emit);
<ElRadio :value="5">5</ElRadio>
</ElRadioGroup>
</ElFormItem>
<ElCard header="菜单设置" class="property-group" shadow="never">
<Draggable
v-model="formData.list"
@ -101,5 +101,3 @@ const formData = useVModel(props, 'modelValue', emit);
</ElForm>
</ComponentContainerProperty>
</template>
<style scoped lang="scss"></style>