feat:【antd】【mall】diy-editor 的 config.ts 同步。

This commit is contained in:
YunaiV
2025-11-03 22:53:13 +08:00
parent bd38cf4c7d
commit 06309e40b8
29 changed files with 394 additions and 674 deletions

View File

@@ -14,16 +14,15 @@ import { componentConfigs } from './mobile/index';
/** 组件库:目前左侧的【基础组件】、【图文组件】部分 */ /** 组件库:目前左侧的【基础组件】、【图文组件】部分 */
defineOptions({ name: 'ComponentLibrary' }); defineOptions({ name: 'ComponentLibrary' });
// 组件列表 /** 组件列表 */
const props = defineProps<{ const props = defineProps<{
list: DiyComponentLibrary[]; list: DiyComponentLibrary[];
}>(); }>();
// 组件分组
const groups = reactive<any[]>([]);
// 展开的折叠面板
const extendGroups = reactive<string[]>([]);
// 监听 list 属性,按照 DiyComponentLibrary 的 name 分组 const groups = reactive<any[]>([]); // 组件分组
const extendGroups = reactive<string[]>([]); // 展开的折叠面板
/** 监听 list 属性,按照 DiyComponentLibrary 的 name 分组 */
watch( watch(
() => props.list, () => props.list,
() => { () => {
@@ -53,7 +52,7 @@ watch(
}, },
); );
// 克隆组件 /** 克隆组件 */
const handleCloneComponent = (component: DiyComponent<any>) => { const handleCloneComponent = (component: DiyComponent<any>) => {
const instance = cloneDeep(component); const instance = cloneDeep(component);
instance.uid = Date.now(); instance.uid = Date.now();
@@ -62,7 +61,9 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
</script> </script>
<template> <template>
<div class="editor-left w-[261px]"> <div
class="editor-left z-[1] w-[261px] shrink-0 select-none shadow-[8px_0_8px_-8px_rgb(0_0_0/0.12)]"
>
<div class="h-full overflow-y-auto"> <div class="h-full overflow-y-auto">
<Collapse v-model:active-key="extendGroups"> <Collapse v-model:active-key="extendGroups">
<CollapsePanel <CollapsePanel
@@ -71,7 +72,7 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
:header="group.name" :header="group.name"
> >
<draggable <draggable
class="component-container" class="flex flex-wrap items-center"
ghost-class="draggable-ghost" ghost-class="draggable-ghost"
item-key="index" item-key="index"
:list="group.components" :list="group.components"
@@ -79,13 +80,22 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
:group="{ name: 'component', pull: 'clone', put: false }" :group="{ name: 'component', pull: 'clone', put: false }"
:clone="handleCloneComponent" :clone="handleCloneComponent"
:animation="200" :animation="200"
:force-fallback="true" :force-fallback="false"
> >
<template #item="{ element }"> <template #item="{ element }">
<div> <div>
<div class="drag-placement">组件放置区域</div> <div class="hidden text-white">组件放置区域</div>
<div class="component"> <div
<IconifyIcon :icon="element.icon" :size="32" /> class="component flex h-[86px] w-[86px] cursor-move flex-col items-center justify-center border-b border-r [&:nth-of-type(3n)]:border-r-0"
:style="{
borderColor: 'var(--ant-color-split)',
}"
>
<IconifyIcon
:icon="element.icon"
:size="32"
class="mb-1 text-gray-500"
/>
<span class="mt-1 text-xs">{{ element.name }}</span> <span class="mt-1 text-xs">{{ element.name }}</span>
</div> </div>
</div> </div>
@@ -99,11 +109,6 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
<style scoped lang="scss"> <style scoped lang="scss">
.editor-left { .editor-left {
z-index: 1;
flex-shrink: 0;
user-select: none;
box-shadow: 8px 0 8px -8px rgb(0 0 0 / 12%);
:deep(.ant-collapse) { :deep(.ant-collapse) {
border-top: none; border-top: none;
} }
@@ -112,8 +117,8 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
border-bottom: none; border-bottom: none;
} }
:deep(.ant-collapse-content) { :deep(.ant-collapse-content-box) {
padding-bottom: 0; padding: 0;
} }
:deep(.ant-collapse-header) { :deep(.ant-collapse-header) {
@@ -124,50 +129,19 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
border-bottom: none; border-bottom: none;
} }
.component-container { /* 组件 hover 和 active 状态(需要 CSS 变量)*/
display: flex;
flex-wrap: wrap;
align-items: center;
}
.component {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 86px;
height: 86px;
cursor: move;
border-right: 1px solid var(--ant-color-border-secondary);
border-bottom: 1px solid var(--ant-color-border-secondary);
.anticon {
margin-bottom: 4px;
color: gray;
}
}
.component.active, .component.active,
.component:hover { .component:hover {
color: var(--ant-color-white); color: var(--ant-color-white);
background: var(--ant-color-primary); background: var(--ant-color-primary);
.anticon { :deep(.iconify) {
color: var(--ant-color-white); color: var(--ant-color-white);
} }
} }
.component:nth-of-type(3n) {
border-right: none;
}
}
/* 拖拽占位提示,默认不显示 */
.drag-placement {
display: none;
color: #fff;
} }
/* 拖拽区域全局样式 */
.drag-area { .drag-area {
/* 拖拽到手机区域时的样式 */ /* 拖拽到手机区域时的样式 */
.draggable-ghost { .draggable-ghost {
@@ -203,14 +177,12 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
background: #5487df; background: #5487df;
} }
/* 拖拽时隐藏组件 */
.component { .component {
display: none; display: none; /* 拖拽时隐藏组件 */
} }
/* 拖拽时显示占位提示 */ .hidden {
.drag-placement { display: block !important; /* 拖拽时显示占位提示 */
display: block;
} }
} }
} }

View File

@@ -2,32 +2,24 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 轮播图属性 */ /** 轮播图属性 */
export interface CarouselProperty { export interface CarouselProperty {
// 类型:默认 | 卡片 type: 'card' | 'default'; // 类型:默认 | 卡片
type: 'card' | 'default'; indicator: 'dot' | 'number'; // 指示器样式:点 | 数字
// 指示器样式:点 | 数字 autoplay: boolean; // 是否自动播放
indicator: 'dot' | 'number'; interval: number; // 播放间隔
// 是否自动播放 height: number; // 轮播高度
autoplay: boolean; items: CarouselItemProperty[]; // 轮播内容
// 播放间隔 style: ComponentStyle; // 组件样式
interval: number;
// 轮播内容
items: CarouselItemProperty[];
// 组件样式
style: ComponentStyle;
}
// 轮播内容属性
export interface CarouselItemProperty {
// 类型:图片 | 视频
type: 'img' | 'video';
// 图片链接
imgUrl: string;
// 视频链接
videoUrl: string;
// 跳转链接
url: string;
} }
// 定义组件 /** 轮播内容属性 */
export interface CarouselItemProperty {
type: 'img' | 'video'; // 类型:图片 | 视频
imgUrl: string; // 图片链接
videoUrl: string; // 视频链接
url: string; // 跳转链接
}
/** 定义组件 */
export const component = { export const component = {
id: 'Carousel', id: 'Carousel',
name: '轮播图', name: '轮播图',
@@ -37,6 +29,7 @@ export const component = {
indicator: 'dot', indicator: 'dot',
autoplay: false, autoplay: false,
interval: 3, interval: 3,
height: 174,
items: [ items: [
{ {
type: 'img', type: 'img',

View File

@@ -2,19 +2,14 @@ import type { DiyComponent } from '../../../util';
/** 分割线属性 */ /** 分割线属性 */
export interface DividerProperty { export interface DividerProperty {
// 高度 height: number; // 高度
height: number; lineWidth: number; // 线宽
// 线宽 paddingType: 'horizontal' | 'none'; // 边距类型
lineWidth: number; lineColor: string; // 颜色
// 边距类型 borderType: 'dashed' | 'dotted' | 'none' | 'solid'; // 类型
paddingType: 'horizontal' | 'none';
// 颜色
lineColor: string;
// 类型
borderType: 'dashed' | 'dotted' | 'none' | 'solid';
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'Divider', id: 'Divider',
name: '分割线', name: '分割线',

View File

@@ -2,19 +2,17 @@ import type { DiyComponent } from '../../../util';
/** 弹窗广告属性 */ /** 弹窗广告属性 */
export interface PopoverProperty { export interface PopoverProperty {
list: PopoverItemProperty[]; list: PopoverItemProperty[]; // 弹窗列表
} }
/** 弹窗广告项目属性 */
export interface PopoverItemProperty { export interface PopoverItemProperty {
// 图片地址 imgUrl: string; // 图片地址
imgUrl: string; url: string; // 跳转连接
// 跳转连接 showType: 'always' | 'once'; // 显示类型:仅显示一次、每次启动都会显示
url: string;
// 显示类型:仅显示一次、每次启动都会显示
showType: 'always' | 'once';
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'Popover', id: 'Popover',
name: '弹窗广告', name: '弹窗广告',

View File

@@ -1,29 +1,20 @@
import type { ComponentStyle, DiyComponent } from '../../../util'; import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品卡片属性 */ /** 优惠劵卡片属性 */
export interface CouponCardProperty { export interface CouponCardProperty {
// 列数 columns: number; // 列数
columns: number; bgImg: string; // 背景图
// 背景图 textColor: string; // 文字颜色
bgImg: string;
// 文字颜色
textColor: string;
// 按钮样式
button: { button: {
// 背景颜色 bgColor: string; // 背景颜色
bgColor: string; color: string; // 文字颜色
// 颜色 }; // 按钮样式
color: string; space: number; // 间距
}; couponIds: number[]; // 优惠券编号列表
// 间距 style: ComponentStyle; // 组件样式
space: number;
// 优惠券编号列表
couponIds: number[];
// 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'CouponCard', id: 'CouponCard',
name: '优惠券', name: '优惠券',

View File

@@ -1,28 +1,21 @@
import type { DiyComponent } from '../../../util'; import type { DiyComponent } from '../../../util';
// 悬浮按钮属性 /** 悬浮按钮属性 */
export interface FloatingActionButtonProperty { export interface FloatingActionButtonProperty {
// 展开方向 direction: 'horizontal' | 'vertical'; // 展开方向
direction: 'horizontal' | 'vertical'; showText: boolean; // 是否显示文字
// 是否显示文字 list: FloatingActionButtonItemProperty[]; // 按钮列表
showText: boolean;
// 按钮列表
list: FloatingActionButtonItemProperty[];
} }
// 悬浮按钮项属性 /** 悬浮按钮项属性 */
export interface FloatingActionButtonItemProperty { export interface FloatingActionButtonItemProperty {
// 图片地址 imgUrl: string; // 图片地址
imgUrl: string; url: string; // 跳转连接
// 跳转连接 text: string; // 文字
url: string; textColor: string; // 文字颜色
// 文字
text: string;
// 文字颜色
textColor: string;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'FloatingActionButton', id: 'FloatingActionButton',
name: '悬浮按钮', name: '悬浮按钮',

View File

@@ -2,31 +2,22 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 热区属性 */ /** 热区属性 */
export interface HotZoneProperty { export interface HotZoneProperty {
// 图片地址 imgUrl: string; // 图片地址
imgUrl: string; list: HotZoneItemProperty[]; // 导航菜单列表
// 导航菜单列表 style: ComponentStyle; // 组件样式
list: HotZoneItemProperty[];
// 组件样式
style: ComponentStyle;
} }
/** 热区项目属性 */ /** 热区项目属性 */
export interface HotZoneItemProperty { export interface HotZoneItemProperty {
// 链接的名称 name: string; // 链接的名称
name: string; url: string; // 链接
// 链接 width: number; //
url: string; height: number; // 高
// top: number; //
width: number; left: number; // 左
// 高
height: number;
// 上
top: number;
// 左
left: number;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'HotZone', id: 'HotZone',
name: '热区', name: '热区',

View File

@@ -2,15 +2,12 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 图片展示属性 */ /** 图片展示属性 */
export interface ImageBarProperty { export interface ImageBarProperty {
// 图片链接 imgUrl: string; // 图片链接
imgUrl: string; url: string; // 跳转链接
// 跳转链接 style: ComponentStyle; // 组件样式
url: string;
// 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'ImageBar', id: 'ImageBar',
name: '图片展示', name: '图片展示',

View File

@@ -2,39 +2,24 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 广告魔方属性 */ /** 广告魔方属性 */
export interface MagicCubeProperty { export interface MagicCubeProperty {
// 上圆角 borderRadiusTop: number; // 上圆角
borderRadiusTop: number; borderRadiusBottom: number; // 下圆角
// 下圆角 space: number; // 间隔
borderRadiusBottom: number; list: MagicCubeItemProperty[]; // 导航菜单列表
// 间隔 style: ComponentStyle; // 组件样式
space: number;
// 导航菜单列表
list: MagicCubeItemProperty[];
// 组件样式
style: ComponentStyle;
} }
/** 广告魔方项目属性 */ /** 广告魔方项目属性 */
export interface MagicCubeItemProperty { export interface MagicCubeItemProperty {
// 图标链接 imgUrl: string; // 图标链接
imgUrl: string; url: string; // 链接
// 链接 width: number; //
url: string; height: number; // 高
// top: number; //
width: number; left: number; // 左
// 高
height: number;
// 上
top: number;
// 左
left: number;
// 右
right: number;
// 下
bottom: number;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'MagicCube', id: 'MagicCube',
name: '广告魔方', name: '广告魔方',

View File

@@ -4,41 +4,28 @@ import { cloneDeep } from '@vben/utils';
/** 宫格导航属性 */ /** 宫格导航属性 */
export interface MenuGridProperty { export interface MenuGridProperty {
// 列数 column: number; // 列数
column: number; list: MenuGridItemProperty[]; // 导航菜单列表
// 导航菜单列表 style: ComponentStyle; // 组件样式
list: MenuGridItemProperty[];
// 组件样式
style: ComponentStyle;
} }
/** 宫格导航项目属性 */ /** 宫格导航项目属性 */
export interface MenuGridItemProperty { export interface MenuGridItemProperty {
// 图标链接 iconUrl: string; // 图标链接
iconUrl: string; title: string; // 标题
// 标题 titleColor: string; // 标题颜色
title: string; subtitle: string; // 副标题
// 标题颜色 subtitleColor: string; // 标题颜色
titleColor: string; url: string; // 链接
// 副标题
subtitle: string;
// 副标题颜色
subtitleColor: string;
// 链接
url: string;
// 角标
badge: { badge: {
// 角标背景颜色 bgColor: string; // 角标背景颜色
bgColor: string; show: boolean; // 是否显示
// 是否显示 text: string; // 角标文字
show: boolean; textColor: string; // 角标文字颜色
// 角标文字
text: string;
// 角标文字颜色
textColor: string;
}; };
} }
/** 宫格导航项目默认属性 */
export const EMPTY_MENU_GRID_ITEM_PROPERTY = { export const EMPTY_MENU_GRID_ITEM_PROPERTY = {
title: '标题', title: '标题',
titleColor: '#333', titleColor: '#333',
@@ -51,7 +38,7 @@ export const EMPTY_MENU_GRID_ITEM_PROPERTY = {
}, },
} as MenuGridItemProperty; } as MenuGridItemProperty;
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'MenuGrid', id: 'MenuGrid',
name: '宫格导航', name: '宫格导航',

View File

@@ -4,28 +4,21 @@ import { cloneDeep } from '@vben/utils';
/** 列表导航属性 */ /** 列表导航属性 */
export interface MenuListProperty { export interface MenuListProperty {
// 导航菜单列表 list: MenuListItemProperty[]; // 导航菜单列表
list: MenuListItemProperty[]; style: ComponentStyle; // 组件样式
// 组件样式
style: ComponentStyle;
} }
/** 列表导航项目属性 */ /** 列表导航项目属性 */
export interface MenuListItemProperty { export interface MenuListItemProperty {
// 图标链接 iconUrl: string; // 图标链接
iconUrl: string; title: string; // 标题
// 标题 titleColor: string; // 标题颜色
title: string; subtitle: string; // 副标题
// 标题颜色 subtitleColor: string; // 标题颜色
titleColor: string; url: string; // 链接
// 副标题
subtitle: string;
// 副标题颜色
subtitleColor: string;
// 链接
url: string;
} }
/** 空的列表导航项目属性 */
export const EMPTY_MENU_LIST_ITEM_PROPERTY = { export const EMPTY_MENU_LIST_ITEM_PROPERTY = {
title: '标题', title: '标题',
titleColor: '#333', titleColor: '#333',
@@ -33,7 +26,7 @@ export const EMPTY_MENU_LIST_ITEM_PROPERTY = {
subtitleColor: '#bbb', subtitleColor: '#bbb',
}; };
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'MenuList', id: 'MenuList',
name: '列表导航', name: '列表导航',

View File

@@ -4,40 +4,28 @@ import { cloneDeep } from '@vben/utils';
/** 菜单导航属性 */ /** 菜单导航属性 */
export interface MenuSwiperProperty { export interface MenuSwiperProperty {
// 布局: 图标+文字 | 图标 layout: 'icon' | 'iconText'; // 布局:图标+文字 | 图标
layout: 'icon' | 'iconText'; row: number; // 行数
// column: number; //
row: number; list: MenuSwiperItemProperty[]; // 导航菜单列表
// 列数 style: ComponentStyle; // 组件样式
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 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 = { export const EMPTY_MENU_SWIPER_ITEM_PROPERTY = {
title: '标题', title: '标题',
titleColor: '#333', titleColor: '#333',
@@ -48,7 +36,7 @@ export const EMPTY_MENU_SWIPER_ITEM_PROPERTY = {
}, },
} as MenuSwiperItemProperty; } as MenuSwiperItemProperty;
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'MenuSwiper', id: 'MenuSwiper',
name: '菜单导航', name: '菜单导航',

View File

@@ -2,56 +2,38 @@ import type { DiyComponent } from '../../../util';
/** 顶部导航栏属性 */ /** 顶部导航栏属性 */
export interface NavigationBarProperty { export interface NavigationBarProperty {
// 背景类型 bgType: 'color' | 'img'; // 背景类型
bgType: 'color' | 'img'; bgColor: string; // 背景颜色
// 背景颜色 bgImg: string; // 图片链接
bgColor: string; styleType: 'inner' | 'normal'; // 样式类型:默认 | 沉浸式
// 图片链接 alwaysShow: boolean; // 常驻显示
bgImg: string; mpCells: NavigationBarCellProperty[]; // 小程序单元格列表
// 样式类型:默认 | 沉浸式 otherCells: NavigationBarCellProperty[]; // 其它平台单元格列表
styleType: 'inner' | 'normal';
// 常驻显示
alwaysShow: boolean;
// 小程序单元格列表
mpCells: NavigationBarCellProperty[];
// 其它平台单元格列表
otherCells: NavigationBarCellProperty[];
// 本地变量
_local: { _local: {
// 预览顶部导航(小程序) previewMp: boolean; // 预览顶部导航(小程序)
previewMp: boolean; previewOther: boolean; // 预览顶部导航(非小程序)
// 预览顶部导航(非小程序) }; // 本地变量
previewOther: boolean;
};
} }
/** 顶部导航栏 - 单元格 属性 */ /** 顶部导航栏 - 单元格 属性 */
export interface NavigationBarCellProperty { export interface NavigationBarCellProperty {
// 类型:文字 | 图片 | 搜索框 type: 'image' | 'search' | 'text'; // 类型:文字 | 图片 | 搜索框
type: 'image' | 'search' | 'text'; width: number; // 宽度
// height: number; //
width: number; top: number; // 顶部位置
// 高度 left: number; // 左侧位置
height: number; text: string; // 文字内容
// 顶部位置 textColor: string; // 文字颜色
top: number; imgUrl: string; // 图片地址
// 左侧位置 url: string; // 图片链接
left: number; backgroundColor: string; // 搜索框:框体颜色
// 文字内容 placeholder: string; // 搜索框:提示文字
text: string; placeholderPosition: string; // 搜索框:提示文字位置
// 文字颜色 showScan: boolean; // 搜索框:是否显示扫一扫
textColor: string; borderRadius: number; // 搜索框:边框圆角半径
// 图片地址
imgUrl: string;
// 图片链接
url: string;
// 搜索框:提示文字
placeholder: string;
// 搜索框:边框圆角半径
borderRadius: number;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'NavigationBar', id: 'NavigationBar',
name: '顶部导航栏', name: '顶部导航栏',

View File

@@ -2,27 +2,20 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 公告栏属性 */ /** 公告栏属性 */
export interface NoticeBarProperty { export interface NoticeBarProperty {
// 图标地址 iconUrl: string; // 图标地址
iconUrl: string; contents: NoticeContentProperty[]; // 公告内容列表
// 公告内容列表 backgroundColor: string; // 背景颜色
contents: NoticeContentProperty[]; textColor: string; // 文字颜色
// 背景颜色 style: ComponentStyle; // 组件样式
backgroundColor: string;
// 文字颜色
textColor: string;
// 组件样式
style: ComponentStyle;
} }
/** 内容属性 */ /** 内容属性 */
export interface NoticeContentProperty { export interface NoticeContentProperty {
// 内容文字 text: string; // 内容文字
text: string; url: string; // 链接地址
// 链接地址
url: string;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'NoticeBar', id: 'NoticeBar',
name: '公告栏', name: '公告栏',

View File

@@ -2,15 +2,12 @@ import type { DiyComponent } from '../../../util';
/** 页面设置属性 */ /** 页面设置属性 */
export interface PageConfigProperty { export interface PageConfigProperty {
// 页面描述 description: string; // 页面描述
description: string; backgroundColor: string; // 页面背景颜色
// 页面背景颜色 backgroundImage: string; // 页面背景图片
backgroundColor: string;
// 页面背景图片
backgroundImage: string;
} }
// 定义页面组件 /** 定义页面组件 */
export const component = { export const component = {
id: 'PageConfig', id: 'PageConfig',
name: '页面设置', name: '页面设置',

View File

@@ -2,63 +2,40 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品卡片属性 */ /** 商品卡片属性 */
export interface ProductCardProperty { export interface ProductCardProperty {
// 布局类型:单列大图 | 单列小图 | 双列 layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列大图 | 单列小图 | 双列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
fields: { fields: {
// 商品简介 introduction: ProductCardFieldProperty; // 商品简介
introduction: ProductCardFieldProperty; marketPrice: ProductCardFieldProperty; // 商品市场价
// 商品市场价 name: ProductCardFieldProperty; // 商品名称
marketPrice: ProductCardFieldProperty; price: ProductCardFieldProperty; // 商品价格
// 商品名称 salesCount: ProductCardFieldProperty; // 商品销量
name: ProductCardFieldProperty; stock: ProductCardFieldProperty; // 商品库存
// 商品价格 }; // 商品字段
price: ProductCardFieldProperty;
// 商品销量
salesCount: ProductCardFieldProperty;
// 商品库存
stock: ProductCardFieldProperty;
};
// 角标
badge: { badge: {
// 角标图片 imgUrl: string; // 角标图片
imgUrl: string; show: boolean; // 是否显示
// 是否显示 }; // 角标
show: boolean;
};
// 按钮
btnBuy: { btnBuy: {
// 文字按钮:背景渐变起始颜色 bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgBeginColor: string; bgEndColor: string; // 文字按钮:背景渐变结束颜色
// 文字按钮:背景渐变结束颜色 imgUrl: string; // 图片按钮:图片地址
bgEndColor: string; text: string; // 文字
// 图片按钮:图片地址 type: 'img' | 'text'; // 类型:文字 | 图片
imgUrl: string; }; // 按钮
// 文字 borderRadiusTop: number; // 上圆角
text: string; borderRadiusBottom: number; // 下圆角
// 类型:文字 | 图片 space: number; // 间距
type: 'img' | 'text'; spuIds: number[]; // 商品编号列表
}; style: ComponentStyle; // 组件样式
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 商品编号列表
spuIds: number[];
// 组件样式
style: ComponentStyle;
}
// 商品字段
export interface ProductCardFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
} }
// 定义组件 /** 商品字段属性 */
export interface ProductCardFieldProperty {
show: boolean; // 是否显示
color: string; // 颜色
}
/** 定义组件 */
export const component = { export const component = {
id: 'ProductCard', id: 'ProductCard',
name: '商品卡片', name: '商品卡片',

View File

@@ -2,42 +2,29 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品栏属性 */ /** 商品栏属性 */
export interface ProductListProperty { export interface ProductListProperty {
// 布局类型:双列 | 三列 | 水平滑动 layoutType: 'horizSwiper' | 'threeCol' | 'twoCol'; // 布局类型:双列 | 三列 | 水平滑动
layoutType: 'horizSwiper' | 'threeCol' | 'twoCol';
// 商品字段
fields: { fields: {
// 商品名称 name: ProductListFieldProperty; // 商品名称
name: ProductListFieldProperty; price: ProductListFieldProperty; // 商品价格
// 商品价格 }; // 商品字段
price: ProductListFieldProperty;
};
// 角标
badge: { badge: {
// 角标图片 imgUrl: string; // 角标图片
imgUrl: string; show: boolean; // 是否显示
// 是否显示 }; // 角标
show: boolean; borderRadiusTop: number; // 上圆角
}; borderRadiusBottom: number; // 下圆角
// 上圆角 space: number; // 间距
borderRadiusTop: number; spuIds: number[]; // 商品编号列表
// 下圆角 style: ComponentStyle; // 组件样式
borderRadiusBottom: number;
// 间距
space: number;
// 商品编号列表
spuIds: number[];
// 组件样式
style: ComponentStyle;
}
// 商品字段
export interface ProductListFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
} }
// 定义组件 /** 商品字段属性 */
export interface ProductListFieldProperty {
show: boolean; // 是否显示
color: string; // 颜色
}
/** 定义组件 */
export const component = { export const component = {
id: 'ProductList', id: 'ProductList',
name: '商品栏', name: '商品栏',

View File

@@ -2,13 +2,11 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 营销文章属性 */ /** 营销文章属性 */
export interface PromotionArticleProperty { export interface PromotionArticleProperty {
// 文章编号 id: number; // 文章编号
id: number; style: ComponentStyle; // 组件样式
// 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'PromotionArticle', id: 'PromotionArticle',
name: '营销文章', name: '营销文章',

View File

@@ -2,64 +2,40 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 拼团属性 */ /** 拼团属性 */
export interface PromotionCombinationProperty { export interface PromotionCombinationProperty {
// 布局类型:单列 | 三列 layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列 | 三列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
fields: { fields: {
// 商品简介 introduction: PromotionCombinationFieldProperty; // 商品简介
introduction: PromotionCombinationFieldProperty; marketPrice: PromotionCombinationFieldProperty; // 市场价
// 市场价 name: PromotionCombinationFieldProperty; // 商品名称
marketPrice: PromotionCombinationFieldProperty; price: PromotionCombinationFieldProperty; // 商品价格
// 商品名称 salesCount: PromotionCombinationFieldProperty; // 商品销量
name: PromotionCombinationFieldProperty; stock: PromotionCombinationFieldProperty; // 商品库存
// 商品价格 }; // 商品字段
price: PromotionCombinationFieldProperty;
// 商品销量
salesCount: PromotionCombinationFieldProperty;
// 商品库存
stock: PromotionCombinationFieldProperty;
};
// 角标
badge: { badge: {
// 角标图片 imgUrl: string; // 角标图片
imgUrl: string; show: boolean; // 是否显示
// 是否显示 }; // 角标
show: boolean;
};
// 按钮
btnBuy: { btnBuy: {
// 文字按钮:背景渐变起始颜色 bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgBeginColor: string; bgEndColor: string; // 文字按钮:背景渐变结束颜色
// 文字按钮:背景渐变结束颜色 imgUrl: string; // 图片按钮:图片地址
bgEndColor: string; text: string; // 文字
// 图片按钮:图片地址 type: 'img' | 'text'; // 类型:文字 | 图片
imgUrl: string; }; // 按钮
// 文字 borderRadiusTop: number; // 上圆角
text: string; borderRadiusBottom: number; // 下圆角
// 类型:文字 | 图片 space: number; // 间距
type: 'img' | 'text'; activityIds: number[]; // 拼团活动编号
}; style: ComponentStyle; // 组件样式
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 拼团活动编号
activityIds: number[];
// 组件样式
style: ComponentStyle;
} }
// 商品字段 /** 商品字段属性 */
export interface PromotionCombinationFieldProperty { export interface PromotionCombinationFieldProperty {
// 是否显示 show: boolean; // 是否显示
show: boolean; color: string; // 颜色
// 颜色
color: string;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'PromotionCombination', id: 'PromotionCombination',
name: '拼团', name: '拼团',

View File

@@ -2,64 +2,41 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 积分商城属性 */ /** 积分商城属性 */
export interface PromotionPointProperty { export interface PromotionPointProperty {
// 布局类型:单列 | 三列 layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列 | 三列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
fields: { fields: {
// 商品简介 introduction: PromotionPointFieldProperty; // 商品简介
introduction: PromotionPointFieldProperty; marketPrice: PromotionPointFieldProperty; // 市场价
// 市场价 name: PromotionPointFieldProperty; // 商品名称
marketPrice: PromotionPointFieldProperty; price: PromotionPointFieldProperty; // 商品价格
// 商品名称 salesCount: PromotionPointFieldProperty; // 商品销量
name: PromotionPointFieldProperty; stock: PromotionPointFieldProperty; // 商品库存
// 商品价格 }; // 商品字段
price: PromotionPointFieldProperty;
// 商品销量
salesCount: PromotionPointFieldProperty;
// 商品库存
stock: PromotionPointFieldProperty;
};
// 角标
badge: { badge: {
// 角标图片 imgUrl: string; // 角标图片
imgUrl: string; show: boolean; // 是否显示
// 是否显示 }; // 角标
show: boolean;
};
// 按钮 // 按钮
btnBuy: { btnBuy: {
// 文字按钮:背景渐变起始颜色 bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgBeginColor: string; bgEndColor: string; // 文字按钮:背景渐变结束颜色
// 文字按钮:背景渐变结束颜色 imgUrl: string; // 图片按钮:图片地址
bgEndColor: string; text: string; // 文字
// 图片按钮:图片地址 type: 'img' | 'text'; // 类型:文字 | 图片
imgUrl: string; }; // 按钮
// 文字 borderRadiusTop: number; // 上圆角
text: string; borderRadiusBottom: number; // 下圆角
// 类型:文字 | 图片 space: number; // 间距
type: 'img' | 'text'; activityIds: number[]; // 积分活动编号
}; style: ComponentStyle; // 组件样式
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 秒杀活动编号
activityIds: number[];
// 组件样式
style: ComponentStyle;
} }
// 商品字段 /** 商品字段属性 */
export interface PromotionPointFieldProperty { export interface PromotionPointFieldProperty {
// 是否显示 show: boolean; // 是否显示
show: boolean; color: string; // 颜色
// 颜色
color: string;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'PromotionPoint', id: 'PromotionPoint',
name: '积分商城', name: '积分商城',

View File

@@ -2,64 +2,40 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 秒杀属性 */ /** 秒杀属性 */
export interface PromotionSeckillProperty { export interface PromotionSeckillProperty {
// 布局类型:单列 | 三列 layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列 | 三列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
fields: { fields: {
// 商品简介 introduction: PromotionSeckillFieldProperty; // 商品简介
introduction: PromotionSeckillFieldProperty; marketPrice: PromotionSeckillFieldProperty; // 市场价
// 市场价 name: PromotionSeckillFieldProperty; // 商品名称
marketPrice: PromotionSeckillFieldProperty; price: PromotionSeckillFieldProperty; // 商品价格
// 商品名称 salesCount: PromotionSeckillFieldProperty; // 商品销量
name: PromotionSeckillFieldProperty; stock: PromotionSeckillFieldProperty; // 商品库存
// 商品价格 }; // 商品字段
price: PromotionSeckillFieldProperty;
// 商品销量
salesCount: PromotionSeckillFieldProperty;
// 商品库存
stock: PromotionSeckillFieldProperty;
};
// 角标
badge: { badge: {
// 角标图片 imgUrl: string; // 角标图片
imgUrl: string; show: boolean; // 是否显示
// 是否显示 }; // 角标
show: boolean;
};
// 按钮
btnBuy: { btnBuy: {
// 文字按钮:背景渐变起始颜色 bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgBeginColor: string; bgEndColor: string; // 文字按钮:背景渐变结束颜色
// 文字按钮:背景渐变结束颜色 imgUrl: string; // 图片按钮:图片地址
bgEndColor: string; text: string; // 文字
// 图片按钮:图片地址 type: 'img' | 'text'; // 类型:文字 | 图片
imgUrl: string; }; // 按钮
// 文字 borderRadiusTop: number; // 上圆角
text: string; borderRadiusBottom: number; // 下圆角
// 类型:文字 | 图片 space: number; // 间距
type: 'img' | 'text'; activityIds: number[]; // 秒杀活动编号
}; style: ComponentStyle; // 组件样式
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 秒杀活动编号
activityIds: number[];
// 组件样式
style: ComponentStyle;
} }
// 商品字段 /** 商品字段属性 */
export interface PromotionSeckillFieldProperty { export interface PromotionSeckillFieldProperty {
// 是否显示 show: boolean; // 是否显示
show: boolean; color: string; // 颜色
// 颜色
color: string;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'PromotionSeckill', id: 'PromotionSeckill',
name: '秒杀', name: '秒杀',

View File

@@ -13,10 +13,10 @@ export interface SearchProperty {
style: ComponentStyle; style: ComponentStyle;
} }
// 文字位置 /** 文字位置 */
export type PlaceholderPosition = 'center' | 'left'; export type PlaceholderPosition = 'center' | 'left';
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'SearchBar', id: 'SearchBar',
name: '搜索框', name: '搜索框',

View File

@@ -2,41 +2,29 @@ import type { DiyComponent } from '../../../util';
/** 底部导航菜单属性 */ /** 底部导航菜单属性 */
export interface TabBarProperty { export interface TabBarProperty {
// 选项列表 items: TabBarItemProperty[]; // 选项列表
items: TabBarItemProperty[]; theme: string; // 主题
// 主题 style: TabBarStyle; // 样式
theme: string;
// 样式
style: TabBarStyle;
} }
// 选项属性 /** 选项属性 */
export interface TabBarItemProperty { export interface TabBarItemProperty {
// 标签文字 text: string; // 标签文字
text: string; url: string; // 链接
// 链接 iconUrl: string; // 默认图标链接
url: string; activeIconUrl: string; // 选中的图标链接
// 默认图标链接
iconUrl: string;
// 选中的图标链接
activeIconUrl: string;
} }
// 样式 /** 样式 */
export interface TabBarStyle { export interface TabBarStyle {
// 背景类型 bgType: 'color' | 'img'; // 背景类型
bgType: 'color' | 'img'; bgColor: string; // 背景颜色
// 背景颜色 bgImg: string; // 图片链接
bgColor: string; color: string; // 默认颜色
// 图片链接 activeColor: string; // 选中的颜色
bgImg: string;
// 默认颜色
color: string;
// 选中的颜色
activeColor: string;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'TabBar', id: 'TabBar',
name: '底部导航', name: '底部导航',

View File

@@ -2,46 +2,28 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 标题栏属性 */ /** 标题栏属性 */
export interface TitleBarProperty { export interface TitleBarProperty {
// 背景图 bgImgUrl: string; // 背景图
bgImgUrl: string; marginLeft: number; // 偏移
// 偏移 textAlign: 'center' | 'left'; // 显示位置
marginLeft: number; title: string; // 主标题
// 显示位置 description: string; // 副标题
textAlign: 'center' | 'left'; titleSize: number; // 标题大小
// 主标题 descriptionSize: number; // 描述大小
title: string; titleWeight: number; // 标题粗细
// 副标题 descriptionWeight: number; // 描述粗细
description: string; titleColor: string; // 标题颜色
// 标题大小 descriptionColor: string; // 描述颜色
titleSize: number; height: number; // 高度
// 描述大小
descriptionSize: number;
// 标题粗细
titleWeight: number;
// 描述粗细
descriptionWeight: number;
// 标题颜色
titleColor: string;
// 描述颜色
descriptionColor: string;
// 高度
height: number;
// 查看更多
more: { more: {
// 是否显示查看更多 show: false; // 是否显示查看更多
show: false; text: string; // 自定义文字
// 自定义文字 type: 'all' | 'icon' | 'text'; // 样式选择
text: string; url: string; // 链接
// 样式选择 }; // 查看更多
type: 'all' | 'icon' | 'text'; style: ComponentStyle; // 组件样式
// 链接
url: string;
};
// 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'TitleBar', id: 'TitleBar',
name: '标题栏', name: '标题栏',

View File

@@ -2,11 +2,10 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 用户卡片属性 */ /** 用户卡片属性 */
export interface UserCardProperty { export interface UserCardProperty {
// 组件样式 style: ComponentStyle; // 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'UserCard', id: 'UserCard',
name: '用户卡片', name: '用户卡片',

View File

@@ -2,11 +2,10 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 用户订单属性 */ /** 用户订单属性 */
export interface UserOrderProperty { export interface UserOrderProperty {
// 组件样式 style: ComponentStyle; // 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'UserOrder', id: 'UserOrder',
name: '用户订单', name: '用户订单',

View File

@@ -2,11 +2,10 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 用户资产属性 */ /** 用户资产属性 */
export interface UserWalletProperty { export interface UserWalletProperty {
// 组件样式 style: ComponentStyle; // 组件样式
style: ComponentStyle;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'UserWallet', id: 'UserWallet',
name: '用户资产', name: '用户资产',

View File

@@ -2,23 +2,18 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 视频播放属性 */ /** 视频播放属性 */
export interface VideoPlayerProperty { export interface VideoPlayerProperty {
// 视频链接 videoUrl: string; // 视频链接
videoUrl: string; posterUrl: string; // 封面链接
// 封面链接 autoplay: boolean; // 是否自动播放
posterUrl: string; style: VideoPlayerStyle; // 组件样式
// 是否自动播放
autoplay: boolean;
// 组件样式
style: VideoPlayerStyle;
} }
// 视频播放样式 /** 视频播放样式 */
export interface VideoPlayerStyle extends ComponentStyle { export interface VideoPlayerStyle extends ComponentStyle {
// 视频高度 height: number; // 视频高度
height: number;
} }
// 定义组件 /** 定义组件 */
export const component = { export const component = {
id: 'VideoPlayer', id: 'VideoPlayer',
name: '视频播放', name: '视频播放',

View File

@@ -3,12 +3,12 @@ import type { DiyComponent, DiyComponentLibrary, PageConfig } from './util';
import { onMounted, ref, unref, watch } from 'vue'; import { onMounted, ref, unref, watch } from 'vue';
import { IFrame } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons'; import { IconifyIcon } from '@vben/icons';
import { cloneDeep, isEmpty, isString } from '@vben/utils'; import { cloneDeep, isEmpty, isString } from '@vben/utils';
import { useQRCode } from '@vueuse/integrations/useQRCode'; import { useQRCode } from '@vueuse/integrations/useQRCode';
import { Button, Card, Modal, Tag, Tooltip } from 'ant-design-vue'; import { Button, Card, Image, Tag, Tooltip } from 'ant-design-vue';
import draggable from 'vuedraggable'; import draggable from 'vuedraggable';
import statusBarImg from '#/assets/imgs/diy/statusBar.png'; import statusBarImg from '#/assets/imgs/diy/statusBar.png';
@@ -37,7 +37,7 @@ const props = defineProps({
previewUrl: { type: String, default: '' }, // 预览地址:提供了预览地址,才会显示预览按钮 previewUrl: { type: String, default: '' }, // 预览地址:提供了预览地址,才会显示预览按钮
}); });
const emits = defineEmits(['reset', 'preview', 'save', 'update:modelValue']); // 工具栏操作 const emits = defineEmits(['reset', 'save', 'update:modelValue']); // 工具栏操作
const qrcode = useQRCode(props.previewUrl, { const qrcode = useQRCode(props.previewUrl, {
errorCorrectionLevel: 'H', errorCorrectionLevel: 'H',
@@ -68,17 +68,20 @@ watch(
isString(props.modelValue) && !isEmpty(props.modelValue) isString(props.modelValue) && !isEmpty(props.modelValue)
? (JSON.parse(props.modelValue) as PageConfig) ? (JSON.parse(props.modelValue) as PageConfig)
: props.modelValue; : props.modelValue;
// TODO @AI这里可以简化么idea 提示 Invalid 'typeof' check: 'modelValue' cannot have type 'string' // noinspection SuspiciousTypeOfGuard
pageConfigComponent.value.property = pageConfigComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.page) || (typeof modelValue !== 'string' && modelValue?.page) ||
PAGE_CONFIG_COMPONENT.property; PAGE_CONFIG_COMPONENT.property;
// noinspection SuspiciousTypeOfGuard
navigationBarComponent.value.property = navigationBarComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.navigationBar) || (typeof modelValue !== 'string' && modelValue?.navigationBar) ||
NAVIGATION_BAR_COMPONENT.property; NAVIGATION_BAR_COMPONENT.property;
// noinspection SuspiciousTypeOfGuard
tabBarComponent.value.property = tabBarComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.tabBar) || (typeof modelValue !== 'string' && modelValue?.tabBar) ||
TAB_BAR_COMPONENT.property; TAB_BAR_COMPONENT.property;
// 查找对应的页面组件 // 查找对应的页面组件
// noinspection SuspiciousTypeOfGuard
pageComponents.value = ( pageComponents.value = (
(typeof modelValue !== 'string' && modelValue?.components) || (typeof modelValue !== 'string' && modelValue?.components) ||
[] []
@@ -99,6 +102,11 @@ watch(
if (!val || selectedComponentIndex.value === -1) { if (!val || selectedComponentIndex.value === -1) {
return; return;
} }
// 如果是基础设置页,默认选中的索引改成 -1为了防止删除组件后切换到此页导致报错
// https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/792
if (props.showTabBar) {
selectedComponentIndex.value = -1;
}
pageComponents.value[selectedComponentIndex.value] = pageComponents.value[selectedComponentIndex.value] =
selectedComponent.value!; selectedComponent.value!;
}, },
@@ -251,12 +259,17 @@ function handleReset() {
emits('reset'); emits('reset');
} }
// TODO @AI搞成 modal 来? const [PreviewModal, previewModalApi] = useVbenModal({
showConfirmButton: false,
showCancelButton: false,
onCancel() {
previewModalApi.close();
},
});
/** 预览 */ /** 预览 */
const previewDialogVisible = ref(false);
function handlePreview() { function handlePreview() {
previewDialogVisible.value = true; previewModalApi.open();
emits('preview');
} }
/** 设置默认选中的组件 */ /** 设置默认选中的组件 */
@@ -457,19 +470,18 @@ onMounted(() => {
</div> </div>
<!-- 预览弹框 --> <!-- 预览弹框 -->
<Modal v-model:open="previewDialogVisible" title="预览" width="700"> <PreviewModal title="预览" class="w-700px">
<div class="flex justify-around"> <div class="flex justify-around">
<IFrame <iframe
:src="previewUrl" :src="previewUrl"
class="h-[667px] w-[375px] rounded-lg border-4 border-solid p-0.5" class="h-[667px] w-[375px] rounded-lg border-4 border-solid p-0.5"
/> ></iframe>
<div class="flex flex-col"> <div class="flex flex-col">
<div class="text-base">手机扫码预览</div> <div class="text-base">手机扫码预览</div>
<img :src="qrcode" alt="qrcode" class="w-1/2" /> <Image :src="qrcode" alt="qrcode" />
<!-- <Qrcode :text="previewUrl" logo="/logo.gif" /> -->
</div> </div>
</div> </div>
</Modal> </PreviewModal>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>