feat:【antd】【mall】diy-editor 修复 element-plus 组件之路:部分解决 21%
This commit is contained in:
@@ -5,6 +5,8 @@ import { ref } from 'vue';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
/** 弹窗广告 */
|
||||
defineOptions({ name: 'Popover' });
|
||||
// 定义属性
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ref } from 'vue';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { Image, message } from 'ant-design-vue';
|
||||
|
||||
/** 悬浮按钮 */
|
||||
defineOptions({ name: 'FloatingActionButton' });
|
||||
|
||||
@@ -3,6 +3,8 @@ import type { MenuListProperty } from './config';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
/** 列表导航 */
|
||||
defineOptions({ name: 'MenuList' });
|
||||
defineProps<{ property: MenuListProperty }>();
|
||||
|
||||
@@ -1,4 +1,145 @@
|
||||
<script lang="ts" setup>
|
||||
import type { NavigationBarCellProperty } from '../config';
|
||||
|
||||
import type { Rect } from '#/views/mall/promotion/components/magic-cube-editor/util';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import {
|
||||
FormItem,
|
||||
Input,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Slider,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import appNavBarMp from '#/assets/imgs/diy/app-nav-bar-mp.png';
|
||||
import UploadImg from '#/components/upload/image-upload.vue';
|
||||
import {
|
||||
AppLinkInput,
|
||||
ColorInput,
|
||||
MagicCubeEditor,
|
||||
} from '#/views/mall/promotion/components';
|
||||
|
||||
// 导航栏属性面板
|
||||
defineOptions({ name: 'NavigationBarCellProperty' });
|
||||
|
||||
const props = defineProps({
|
||||
isMp: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
modelValue: {
|
||||
type: Array as () => NavigationBarCellProperty[],
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const cellList = useVModel(props, 'modelValue', emit);
|
||||
|
||||
// 单元格数量:小程序6个(右侧胶囊按钮占了2个),其它平台8个
|
||||
const cellCount = computed(() => (props.isMp ? 6 : 8));
|
||||
|
||||
// 转换为Rect格式的数据
|
||||
const rectList = computed<Rect[]>(() => {
|
||||
return cellList.value.map((cell) => ({
|
||||
left: cell.left,
|
||||
top: cell.top,
|
||||
width: cell.width,
|
||||
height: cell.height,
|
||||
right: cell.left + cell.width,
|
||||
bottom: cell.top + cell.height,
|
||||
}));
|
||||
});
|
||||
|
||||
// 选中的热区
|
||||
const selectedHotAreaIndex = ref(0);
|
||||
const handleHotAreaSelected = (
|
||||
cellValue: NavigationBarCellProperty,
|
||||
index: number,
|
||||
) => {
|
||||
selectedHotAreaIndex.value = index;
|
||||
if (!cellValue.type) {
|
||||
cellValue.type = 'text';
|
||||
cellValue.textColor = '#111111';
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-40px flex items-center justify-center">
|
||||
<MagicCubeEditor
|
||||
v-model="rectList"
|
||||
:cols="cellCount"
|
||||
:cube-size="38"
|
||||
:rows="1"
|
||||
class="m-b-16px"
|
||||
@hot-area-selected="handleHotAreaSelected"
|
||||
/>
|
||||
<img
|
||||
v-if="isMp"
|
||||
alt=""
|
||||
style="width: 76px; height: 30px"
|
||||
:src="appNavBarMp"
|
||||
/>
|
||||
</div>
|
||||
<template v-for="(cell, cellIndex) in cellList" :key="cellIndex">
|
||||
<template v-if="selectedHotAreaIndex === Number(cellIndex)">
|
||||
<FormItem :label="`类型`">
|
||||
<RadioGroup v-model:value="cell.type">
|
||||
<Radio value="text">文字</Radio>
|
||||
<Radio value="image">图片</Radio>
|
||||
<Radio value="search">搜索框</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<!-- 1. 文字 -->
|
||||
<template v-if="cell.type === 'text'">
|
||||
<FormItem :label="`内容`">
|
||||
<Input v-model:value="cell!.text" :maxlength="10" show-count />
|
||||
</FormItem>
|
||||
<FormItem :label="`颜色`">
|
||||
<ColorInput v-model="cell!.textColor" />
|
||||
</FormItem>
|
||||
<FormItem :label="`链接`">
|
||||
<AppLinkInput v-model="cell.url" />
|
||||
</FormItem>
|
||||
</template>
|
||||
<!-- 2. 图片 -->
|
||||
<template v-else-if="cell.type === 'image'">
|
||||
<FormItem :label="`图片`">
|
||||
<UploadImg
|
||||
v-model="cell.imgUrl"
|
||||
:limit="1"
|
||||
height="56px"
|
||||
width="56px"
|
||||
:show-description="false"
|
||||
>
|
||||
<template #tip>建议尺寸 56*56</template>
|
||||
</UploadImg>
|
||||
</FormItem>
|
||||
<FormItem :label="`链接`">
|
||||
<AppLinkInput v-model="cell.url" />
|
||||
</FormItem>
|
||||
</template>
|
||||
<!-- 3. 搜索框 -->
|
||||
<template v-else>
|
||||
<FormItem :label="`提示文字`">
|
||||
<Input v-model:value="cell.placeholder" :maxlength="10" show-count />
|
||||
</FormItem>
|
||||
<FormItem :label="`圆角`">
|
||||
<Slider
|
||||
v-model:value="cell.borderRadius"
|
||||
:max="100"
|
||||
:min="0"
|
||||
/>
|
||||
</FormItem>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import type { NoticeBarProperty } from './config';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Divider, Image } from 'ant-design-vue';
|
||||
|
||||
/** 公告栏 */
|
||||
defineOptions({ name: 'NoticeBar' });
|
||||
|
||||
defineProps<{ property: NoticeBarProperty }>();
|
||||
const props = defineProps<{ property: NoticeBarProperty }>();
|
||||
|
||||
// 自动轮播
|
||||
const activeIndex = ref(0);
|
||||
setInterval(() => {
|
||||
const contents = props.property.contents || [];
|
||||
activeIndex.value = (activeIndex.value + 1) % (contents.length || 1);
|
||||
}, 3000);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -17,18 +28,11 @@ defineProps<{ property: NoticeBarProperty }>();
|
||||
color: property.textColor,
|
||||
}"
|
||||
>
|
||||
<ElImage :src="property.iconUrl" class="h-[18px]" />
|
||||
<ElDivider direction="vertical" />
|
||||
<ElCarousel
|
||||
height="24px"
|
||||
direction="vertical"
|
||||
:autoplay="true"
|
||||
class="flex-1 pr-2"
|
||||
>
|
||||
<ElCarouselItem v-for="(item, index) in property.contents" :key="index">
|
||||
<div class="h-6 truncate leading-6">{{ item.text }}</div>
|
||||
</ElCarouselItem>
|
||||
</ElCarousel>
|
||||
<Image :src="property.iconUrl" class="h-[18px]" :preview="false" />
|
||||
<Divider type="vertical" />
|
||||
<div class="flex-1 pr-2 h-6 truncate leading-6">
|
||||
{{ property.contents?.[activeIndex]?.text }}
|
||||
</div>
|
||||
<IconifyIcon icon="ep:arrow-right" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -7,6 +7,8 @@ import { ref, watch } from 'vue';
|
||||
|
||||
import { fenToYuan } from '@vben/utils';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
import * as ProductSpuApi from '#/api/mall/product/spu';
|
||||
|
||||
/** 商品卡片 */
|
||||
|
||||
@@ -8,6 +8,8 @@ import { ref, watch } from 'vue';
|
||||
|
||||
import { fenToYuan } from '@vben/utils';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
import * as ProductSpuApi from '#/api/mall/product/spu';
|
||||
import * as CombinationActivityApi from '#/api/mall/promotion/combination/combinationActivity';
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import { ref, watch } from 'vue';
|
||||
|
||||
import { fenToYuan } from '@vben/utils';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
import * as ProductSpuApi from '#/api/mall/product/spu';
|
||||
import * as PointActivityApi from '#/api/mall/promotion/point';
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import { ref, watch } from 'vue';
|
||||
|
||||
import { fenToYuan } from '@vben/utils';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
import * as ProductSpuApi from '#/api/mall/product/spu';
|
||||
import * as SeckillActivityApi from '#/api/mall/promotion/seckill/seckillActivity';
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import type { TabBarProperty } from './config';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
/** 页面底部导航栏 */
|
||||
defineOptions({ name: 'TabBar' });
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import type { TitleBarProperty } from './config';
|
||||
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
/** 标题栏 */
|
||||
defineOptions({ name: 'TitleBar' });
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import type { VideoPlayerProperty } from './config';
|
||||
|
||||
import { Image } from 'ant-design-vue';
|
||||
|
||||
/** 视频播放 */
|
||||
defineOptions({ name: 'VideoPlayer' });
|
||||
|
||||
|
||||
@@ -252,13 +252,13 @@ const handleDeleteComponent = (index: number) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 注入无感刷新页面函数
|
||||
const reload = inject<() => void>('reload'); // TODO @芋艿:是 vue3 + element-plus 独有的,可以清理掉。
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
if (reload) reload();
|
||||
emits('reset');
|
||||
};
|
||||
// // 注入无感刷新页面函数
|
||||
// const reload = inject<() => void>('reload'); // TODO @芋艿:是 vue3 + element-plus 独有的,可以清理掉。
|
||||
// // 重置
|
||||
// const handleReset = () => {
|
||||
// if (reload) reload();
|
||||
// emits('reset');
|
||||
// };
|
||||
|
||||
// 预览
|
||||
const previewDialogVisible = ref(false);
|
||||
|
||||
@@ -261,13 +261,13 @@ const handleDeleteComponent = (index: number) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 注入无感刷新页面函数
|
||||
const reload = inject<() => void>('reload'); // TODO @芋艿:是 vue3 + element-plus 独有的,可以清理掉。
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
if (reload) reload();
|
||||
emits('reset');
|
||||
};
|
||||
// // 注入无感刷新页面函数
|
||||
// const reload = inject<() => void>('reload'); // TODO @芋艿:是 vue3 + element-plus 独有的,可以清理掉。
|
||||
// // 重置
|
||||
// const handleReset = () => {
|
||||
// if (reload) reload();
|
||||
// emits('reset');
|
||||
// };
|
||||
|
||||
// 预览
|
||||
const previewDialogVisible = ref(false);
|
||||
|
||||
Reference in New Issue
Block a user