📖 code review:店铺装修逻辑

This commit is contained in:
YunaiV 2023-12-20 23:01:09 +08:00
parent b86f082306
commit 9591ed7084
6 changed files with 32 additions and 12 deletions

View File

@ -8,11 +8,11 @@
<component :is="component.id" :property="component.property" /> <component :is="component.id" :property="component.property" />
</div> </div>
<div class="component-wrap"> <div class="component-wrap">
<!-- 左侧组件名 --> <!-- 左侧组件名悬浮的小贴条 -->
<div class="component-name" v-if="component.name"> <div class="component-name" v-if="component.name">
{{ component.name }} {{ component.name }}
</div> </div>
<!-- 组件操作工具栏 --> <!-- 组件操作工具栏 -->
<div class="component-toolbar" v-if="showToolbar && component.name && active"> <div class="component-toolbar" v-if="showToolbar && component.name && active">
<VerticalButtonGroup type="primary"> <VerticalButtonGroup type="primary">
<el-tooltip content="上移" placement="right"> <el-tooltip content="上移" placement="right">
@ -54,7 +54,7 @@ import { propTypes } from '@/utils/propTypes'
import { object } from 'vue-types' import { object } from 'vue-types'
/** /**
* 组件容器 * 组件容器目前在中间部分
* 用于包裹组件为组件提供 背景外边距内边距边框等样式 * 用于包裹组件为组件提供 背景外边距内边距边框等样式
*/ */
defineOptions({ name: 'ComponentContainer' }) defineOptions({ name: 'ComponentContainer' })

View File

@ -1,8 +1,11 @@
<template> <template>
<el-tabs stretch> <el-tabs stretch>
<!-- 每个组件的自定义内容 -->
<el-tab-pane label="内容" v-if="$slots.default"> <el-tab-pane label="内容" v-if="$slots.default">
<slot></slot> <slot></slot>
</el-tab-pane> </el-tab-pane>
<!-- 每个组件的通用内容 -->
<el-tab-pane label="样式" lazy> <el-tab-pane label="样式" lazy>
<el-card header="组件样式" class="property-group"> <el-card header="组件样式" class="property-group">
<el-form :model="formData" label-width="80px"> <el-form :model="formData" label-width="80px">
@ -51,7 +54,7 @@
import { ComponentStyle, usePropertyForm } from '@/components/DiyEditor/util' import { ComponentStyle, usePropertyForm } from '@/components/DiyEditor/util'
/** /**
* 组件容器属性 * 组件容器属性目前右边部分
* 用于包裹组件为组件提供 背景外边距内边距边框等样式 * 用于包裹组件为组件提供 背景外边距内边距边框等样式
*/ */
defineOptions({ name: 'ComponentContainer' }) defineOptions({ name: 'ComponentContainer' })

View File

@ -41,16 +41,19 @@ import { componentConfigs } from '../components/mobile/index'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { DiyComponent, DiyComponentLibrary } from '@/components/DiyEditor/util' import { DiyComponent, DiyComponentLibrary } from '@/components/DiyEditor/util'
/** 组件库 */ /** 组件库:目前左侧的【基础组件】、【图文组件】部分 */
defineOptions({ name: 'ComponentLibrary' }) defineOptions({ name: 'ComponentLibrary' })
// //
const props = defineProps<{ const props = defineProps<{
list: DiyComponentLibrary[] list: DiyComponentLibrary[]
}>() }>()
//
const groups = reactive<any[]>([]) const groups = reactive<any[]>([])
// //
const extendGroups = reactive<string[]>([]) const extendGroups = reactive<string[]>([])
// list DiyComponentLibrary name
watch( watch(
() => props.list, () => props.list,
() => { () => {

View File

@ -27,11 +27,12 @@
</el-tooltip> </el-tooltip>
</el-button-group> </el-button-group>
</el-header> </el-header>
<!-- 中心区域 --> <!-- 中心区域 -->
<el-container class="editor-container"> <el-container class="editor-container">
<!-- 左侧组件库 --> <!-- 左侧组件库ComponentLibrary -->
<ComponentLibrary ref="componentLibrary" :list="libs" v-if="libs && libs.length > 0" /> <ComponentLibrary ref="componentLibrary" :list="libs" v-if="libs && libs.length > 0" />
<!-- 中心设计区域 --> <!-- 中心设计区域ComponentContainer -->
<div class="editor-center page-prop-area" @click="handlePageSelected"> <div class="editor-center page-prop-area" @click="handlePageSelected">
<!-- 手机顶部 --> <!-- 手机顶部 -->
<div class="editor-design-top"> <div class="editor-design-top">
@ -132,7 +133,7 @@
</template> </template>
</div> </div>
</div> </div>
<!-- 右侧属性面板 --> <!-- 右侧属性面板ComponentContainerProperty -->
<el-aside class="editor-right" width="350px" v-if="selectedComponent?.property"> <el-aside class="editor-right" width="350px" v-if="selectedComponent?.property">
<el-card <el-card
shadow="never" shadow="never"
@ -160,6 +161,7 @@
</el-aside> </el-aside>
</el-container> </el-container>
</el-container> </el-container>
<!-- 预览弹框 --> <!-- 预览弹框 -->
<Dialog v-model="previewDialogVisible" title="预览" width="700"> <Dialog v-model="previewDialogVisible" title="预览" width="700">
<div class="flex justify-around"> <div class="flex justify-around">
@ -231,6 +233,7 @@ const props = defineProps({
}) })
// //
// pageConfigComponent navigationBarComponentpageComponentstabBarComponent
watch( watch(
() => props.modelValue, () => props.modelValue,
() => { () => {
@ -251,6 +254,7 @@ watch(
immediate: true immediate: true
} }
) )
// //
const handleSave = () => { const handleSave = () => {
const pageConfig = { const pageConfig = {
@ -303,7 +307,7 @@ const handleTabBarSelected = () => {
handleComponentSelected(unref(tabBarComponent)) handleComponentSelected(unref(tabBarComponent))
} }
// //
const handleComponentChange = (dragEvent: any) => { const handleComponentChange = (dragEvent: any) => {
// //
if (dragEvent.added) { if (dragEvent.added) {
@ -327,19 +331,21 @@ const swapComponent = (oldIndex: number, newIndex: number) => {
selectedComponentIndex.value = newIndex selectedComponentIndex.value = newIndex
} }
/** 移动组件 */ /** 移动组件(上移、下移) */
const handleMoveComponent = (index: number, direction: number) => { const handleMoveComponent = (index: number, direction: number) => {
const newIndex = index + direction const newIndex = index + direction
if (newIndex < 0 || newIndex >= pageComponents.value.length) return if (newIndex < 0 || newIndex >= pageComponents.value.length) return
swapComponent(index, newIndex) swapComponent(index, newIndex)
} }
/** 复制组件 */ /** 复制组件 */
const handleCopyComponent = (index: number) => { const handleCopyComponent = (index: number) => {
const component = cloneDeep(pageComponents.value[index]) const component = cloneDeep(pageComponents.value[index])
component.uid = new Date().getTime() component.uid = new Date().getTime()
pageComponents.value.splice(index + 1, 0, component) pageComponents.value.splice(index + 1, 0, component)
} }
/** /**
* 删除组件 * 删除组件
* @param index 当前组件index * @param index 当前组件index
@ -371,6 +377,7 @@ const handleReset = () => {
if (reload) reload() if (reload) reload()
emits('reset') emits('reset')
} }
// //
const previewDialogVisible = ref(false) const previewDialogVisible = ref(false)
const handlePreview = () => { const handlePreview = () => {
@ -388,10 +395,12 @@ const setDefaultSelectedComponent = () => {
selectedComponent.value = unref(tabBarComponent) selectedComponent.value = unref(tabBarComponent)
} }
} }
watch( watch(
() => [props.showPageConfig, props.showNavigationBar, props.showTabBar], () => [props.showPageConfig, props.showNavigationBar, props.showTabBar],
() => setDefaultSelectedComponent() () => setDefaultSelectedComponent()
) )
onMounted(() => setDefaultSelectedComponent()) onMounted(() => setDefaultSelectedComponent())
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -472,7 +472,9 @@ const remainingRouter: AppRouteRecordRaw[] = [
meta: { meta: {
title: '模板装修', title: '模板装修',
noCache: true, noCache: true,
hidden: true hidden: true,
// TODO @疯狂:建议 menu 那的 /mall/promotion/diy-template/diy-template 改成 /mall/promotion/diy/template
activeMenu: '/mall/promotion/diy-template/diy-template'
}, },
component: () => import('@/views/mall/promotion/diy/template/decorate.vue') component: () => import('@/views/mall/promotion/diy/template/decorate.vue')
}, },
@ -482,7 +484,9 @@ const remainingRouter: AppRouteRecordRaw[] = [
meta: { meta: {
title: '页面装修', title: '页面装修',
noCache: true, noCache: true,
hidden: true hidden: true,
// TODO @疯狂:建议 menu 那的 /mall/promotion/diy-template/diy-page 改成 /mall/promotion/diy/page
activeMenu: '/mall/promotion/diy-template/diy-page'
}, },
component: () => import('@/views/mall/promotion/diy/page/decorate.vue') component: () => import('@/views/mall/promotion/diy/page/decorate.vue')
} }

View File

@ -30,6 +30,7 @@ const getPageDetail = async (id: any) => {
formLoading.value = false formLoading.value = false
} }
} }
// //
const submitForm = async () => { const submitForm = async () => {
// //