feat:【mall】diy editor 的 hot-zone 代码优化(50%)
This commit is contained in:
@@ -2,10 +2,9 @@ import type { StyleValue } from 'vue';
|
||||
|
||||
import type { HotZoneItemProperty } from '../../config';
|
||||
|
||||
// 热区的最小宽高
|
||||
export const HOT_ZONE_MIN_SIZE = 100;
|
||||
export const HOT_ZONE_MIN_SIZE = 100; // 热区的最小宽高
|
||||
|
||||
// 控制的类型
|
||||
/** 控制的类型 */
|
||||
export enum CONTROL_TYPE_ENUM {
|
||||
LEFT,
|
||||
TOP,
|
||||
@@ -13,14 +12,14 @@ export enum CONTROL_TYPE_ENUM {
|
||||
HEIGHT,
|
||||
}
|
||||
|
||||
// 定义热区的控制点
|
||||
/** 定义热区的控制点 */
|
||||
export interface ControlDot {
|
||||
position: string;
|
||||
types: CONTROL_TYPE_ENUM[];
|
||||
style: StyleValue;
|
||||
}
|
||||
|
||||
// 热区的8个控制点
|
||||
/** 热区的 8 个控制点 */
|
||||
export const CONTROL_DOT_LIST = [
|
||||
{
|
||||
position: '左上角',
|
||||
@@ -98,10 +97,10 @@ export const CONTROL_DOT_LIST = [
|
||||
] as ControlDot[];
|
||||
|
||||
// region 热区的缩放
|
||||
// 热区的缩放比例
|
||||
export const HOT_ZONE_SCALE_RATE = 2;
|
||||
// 缩小:缩回适合手机屏幕的大小
|
||||
export const zoomOut = (list?: HotZoneItemProperty[]) => {
|
||||
export const HOT_ZONE_SCALE_RATE = 2; // 热区的缩放比例
|
||||
|
||||
/** 缩小:缩回适合手机屏幕的大小 */
|
||||
export function zoomOut(list?: HotZoneItemProperty[]) {
|
||||
return (
|
||||
list?.map((hotZone) => ({
|
||||
...hotZone,
|
||||
@@ -111,9 +110,10 @@ export const zoomOut = (list?: HotZoneItemProperty[]) => {
|
||||
height: (hotZone.height /= HOT_ZONE_SCALE_RATE),
|
||||
})) || []
|
||||
);
|
||||
};
|
||||
// 放大:作用是为了方便在电脑屏幕上编辑
|
||||
export const zoomIn = (list?: HotZoneItemProperty[]) => {
|
||||
}
|
||||
|
||||
/** 放大:作用是为了方便在电脑屏幕上编辑 */
|
||||
export function zoomIn(list?: HotZoneItemProperty[]) {
|
||||
return (
|
||||
list?.map((hotZone) => ({
|
||||
...hotZone,
|
||||
@@ -123,7 +123,8 @@ export const zoomIn = (list?: HotZoneItemProperty[]) => {
|
||||
height: (hotZone.height *= HOT_ZONE_SCALE_RATE),
|
||||
})) || []
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,8 @@ import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { ElButton, ElDialog, ElImage } from 'element-plus';
|
||||
|
||||
import { AppLinkSelectDialog } from '#/views/mall/promotion/components';
|
||||
|
||||
import {
|
||||
CONTROL_DOT_LIST,
|
||||
CONTROL_TYPE_ENUM,
|
||||
@@ -22,7 +24,7 @@ import {
|
||||
/** 热区编辑对话框 */
|
||||
defineOptions({ name: 'HotZoneEditDialog' });
|
||||
|
||||
// 定义属性
|
||||
/** 定义属性 */
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Array<HotZoneItemProperty>,
|
||||
@@ -33,51 +35,53 @@ const props = defineProps({
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const formData = ref<HotZoneItemProperty[]>([]);
|
||||
|
||||
// 弹窗的是否显示
|
||||
const dialogVisible = ref(false);
|
||||
// 打开弹窗
|
||||
const dialogVisible = ref(false); // 弹窗的是否显示
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = () => {
|
||||
// 放大
|
||||
formData.value = zoomIn(props.modelValue);
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
// 提供 open 方法,用于打开弹窗
|
||||
defineExpose({ open });
|
||||
|
||||
// 热区容器
|
||||
const container = ref<HTMLDivElement>();
|
||||
defineExpose({ open }); // 提供 open 方法,用于打开弹窗
|
||||
|
||||
// 增加热区
|
||||
const handleAdd = () => {
|
||||
const container = ref<HTMLDivElement>(); // 热区容器
|
||||
|
||||
/** 增加热区 */
|
||||
function handleAdd() {
|
||||
formData.value.push({
|
||||
width: HOT_ZONE_MIN_SIZE,
|
||||
height: HOT_ZONE_MIN_SIZE,
|
||||
top: 0,
|
||||
left: 0,
|
||||
} as HotZoneItemProperty);
|
||||
};
|
||||
// 删除热区
|
||||
const handleRemove = (hotZone: HotZoneItemProperty) => {
|
||||
formData.value = formData.value.filter((item) => item !== hotZone);
|
||||
};
|
||||
}
|
||||
|
||||
// 移动热区
|
||||
const handleMove = (item: HotZoneItemProperty, e: MouseEvent) => {
|
||||
/** 删除热区 */
|
||||
function handleRemove(hotZone: HotZoneItemProperty) {
|
||||
formData.value = formData.value.filter((item) => item !== hotZone);
|
||||
}
|
||||
|
||||
/** 移动热区 */
|
||||
function handleMove(item: HotZoneItemProperty, e: MouseEvent) {
|
||||
useDraggable(item, e, (left, top, _, __, moveWidth, moveHeight) => {
|
||||
setLeft(item, left + moveWidth);
|
||||
setTop(item, top + moveHeight);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 调整热区大小、位置
|
||||
const handleResize = (
|
||||
/** 调整热区大小、位置 */
|
||||
function handleResize(
|
||||
item: HotZoneItemProperty,
|
||||
ctrlDot: ControlDot,
|
||||
e: MouseEvent,
|
||||
) => {
|
||||
) {
|
||||
useDraggable(item, e, (left, top, width, height, moveWidth, moveHeight) => {
|
||||
ctrlDot.types.forEach((type) => {
|
||||
switch (type) {
|
||||
@@ -112,23 +116,25 @@ const handleResize = (
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 设置X轴坐标
|
||||
const setLeft = (item: HotZoneItemProperty, left: number) => {
|
||||
/** 设置 X 轴坐标 */
|
||||
function setLeft(item: HotZoneItemProperty, left: number) {
|
||||
// 不能超出容器
|
||||
if (left >= 0 && left <= container.value!.offsetWidth - item.width) {
|
||||
item.left = left;
|
||||
}
|
||||
};
|
||||
// 设置Y轴坐标
|
||||
const setTop = (item: HotZoneItemProperty, top: number) => {
|
||||
}
|
||||
|
||||
/** 设置Y轴坐标 */
|
||||
function setTop(item: HotZoneItemProperty, top: number) {
|
||||
// 不能超出容器
|
||||
if (top >= 0 && top <= container.value!.offsetHeight - item.height) {
|
||||
item.top = top;
|
||||
}
|
||||
};
|
||||
// 设置宽度
|
||||
}
|
||||
|
||||
/** 设置宽度 */
|
||||
const setWidth = (item: HotZoneItemProperty, width: number) => {
|
||||
// 不能小于最小宽度 && 不能超出容器右边
|
||||
if (
|
||||
@@ -138,7 +144,8 @@ const setWidth = (item: HotZoneItemProperty, width: number) => {
|
||||
item.width = width;
|
||||
}
|
||||
};
|
||||
// 设置高度
|
||||
|
||||
/** 设置高度 */
|
||||
const setHeight = (item: HotZoneItemProperty, height: number) => {
|
||||
// 不能小于最小高度 && 不能超出容器底部
|
||||
if (
|
||||
@@ -149,13 +156,12 @@ const setHeight = (item: HotZoneItemProperty, height: number) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理对话框关闭
|
||||
/** 处理对话框关闭 */
|
||||
const handleSubmit = () => {
|
||||
// 会自动触发handleClose
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
// 处理对话框关闭
|
||||
/** 处理对话框关闭 */
|
||||
const handleClose = () => {
|
||||
// 缩小
|
||||
const list = zoomOut(formData.value);
|
||||
@@ -164,12 +170,16 @@ const handleClose = () => {
|
||||
|
||||
const activeHotZone = ref<HotZoneItemProperty>();
|
||||
const appLinkDialogRef = ref();
|
||||
|
||||
const handleShowAppLinkDialog = (hotZone: HotZoneItemProperty) => {
|
||||
activeHotZone.value = hotZone;
|
||||
appLinkDialogRef.value.open(hotZone.url);
|
||||
};
|
||||
|
||||
const handleAppLinkChange = (appLink: AppLink) => {
|
||||
if (!appLink || !activeHotZone.value) return;
|
||||
if (!appLink || !activeHotZone.value) {
|
||||
return;
|
||||
}
|
||||
activeHotZone.value.name = appLink.name;
|
||||
activeHotZone.value.url = appLink.path;
|
||||
};
|
||||
@@ -231,6 +241,7 @@ const handleAppLinkChange = (appLink: AppLink) => {
|
||||
</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<AppLinkSelectDialog
|
||||
ref="appLinkDialogRef"
|
||||
@app-link-change="handleAppLinkChange"
|
||||
|
||||
@@ -2,31 +2,22 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
|
||||
|
||||
/** 热区属性 */
|
||||
export interface HotZoneProperty {
|
||||
// 图片地址
|
||||
imgUrl: string;
|
||||
// 导航菜单列表
|
||||
list: HotZoneItemProperty[];
|
||||
// 组件样式
|
||||
style: ComponentStyle;
|
||||
imgUrl: string; // 图片地址
|
||||
list: HotZoneItemProperty[]; // 导航菜单列表
|
||||
style: ComponentStyle; // 组件样式
|
||||
}
|
||||
|
||||
/** 热区项目属性 */
|
||||
export interface HotZoneItemProperty {
|
||||
// 链接的名称
|
||||
name: string;
|
||||
// 链接
|
||||
url: string;
|
||||
// 宽
|
||||
width: number;
|
||||
// 高
|
||||
height: number;
|
||||
// 上
|
||||
top: number;
|
||||
// 左
|
||||
left: number;
|
||||
name: string; // 链接的名称
|
||||
url: string; // 链接
|
||||
width: number; // 宽
|
||||
height: number; // 高
|
||||
top: number; // 上
|
||||
left: number; // 左
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
/** 定义组件 */
|
||||
export const component = {
|
||||
id: 'HotZone',
|
||||
name: '热区',
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ElImage } from 'element-plus';
|
||||
|
||||
/** 热区 */
|
||||
defineOptions({ name: 'HotZone' });
|
||||
|
||||
const props = defineProps<{ property: HotZoneProperty }>();
|
||||
</script>
|
||||
|
||||
|
||||
@@ -15,12 +15,14 @@ import HotZoneEditDialog from './components/hot-zone-edit-dialog/index.vue';
|
||||
defineOptions({ name: 'HotZoneProperty' });
|
||||
|
||||
const props = defineProps<{ modelValue: HotZoneProperty }>();
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const formData = useVModel(props, 'modelValue', emit);
|
||||
|
||||
// 热区编辑对话框
|
||||
const editDialogRef = ref();
|
||||
// 打开热区编辑对话框
|
||||
const editDialogRef = ref(); // 热区编辑对话框
|
||||
|
||||
/** 打开热区编辑对话框 */
|
||||
const handleOpenEditDialog = () => {
|
||||
editDialogRef.value.open();
|
||||
};
|
||||
@@ -49,6 +51,7 @@ const handleOpenEditDialog = () => {
|
||||
设置热区
|
||||
</ElButton>
|
||||
</ComponentContainerProperty>
|
||||
|
||||
<!-- 热区编辑对话框 -->
|
||||
<HotZoneEditDialog
|
||||
ref="editDialogRef"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export { default as AppLinkSelectDialog } from './app-link-input/app-link-select-dialog.vue';
|
||||
export { default as AppLinkInput } from './app-link-input/index.vue';
|
||||
export { default as ColorInput } from './color-input/index.vue';
|
||||
export { default as DiyEditor } from './diy-editor/index.vue';
|
||||
|
||||
Reference in New Issue
Block a user