parent
							
								
									c57db2bf09
								
							
						
					
					
						commit
						b890915539
					
				| 
						 | 
				
			
			@ -8,11 +8,11 @@
 | 
			
		|||
      <component :is="component.id" :property="component.property" />
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="component-wrap">
 | 
			
		||||
      <!-- 左侧组件名 -->
 | 
			
		||||
      <!-- 左侧:组件名(悬浮的小贴条) -->
 | 
			
		||||
      <div class="component-name" v-if="component.name">
 | 
			
		||||
        {{ component.name }}
 | 
			
		||||
      </div>
 | 
			
		||||
      <!-- 左侧:组件操作工具栏 -->
 | 
			
		||||
      <!-- 右侧:组件操作工具栏 -->
 | 
			
		||||
      <div class="component-toolbar" v-if="showToolbar && component.name && active">
 | 
			
		||||
        <VerticalButtonGroup type="primary">
 | 
			
		||||
          <el-tooltip content="上移" placement="right">
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ import { propTypes } from '@/utils/propTypes'
 | 
			
		|||
import { object } from 'vue-types'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 组件容器
 | 
			
		||||
 * 组件容器:目前在中间部分
 | 
			
		||||
 * 用于包裹组件,为组件提供 背景、外边距、内边距、边框等样式
 | 
			
		||||
 */
 | 
			
		||||
defineOptions({ name: 'ComponentContainer' })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <el-tabs stretch>
 | 
			
		||||
    <!-- 每个组件的自定义内容 -->
 | 
			
		||||
    <el-tab-pane label="内容" v-if="$slots.default">
 | 
			
		||||
      <slot></slot>
 | 
			
		||||
    </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
    <!-- 每个组件的通用内容 -->
 | 
			
		||||
    <el-tab-pane label="样式" lazy>
 | 
			
		||||
      <el-card header="组件样式" class="property-group">
 | 
			
		||||
        <el-form :model="formData" label-width="80px">
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +54,7 @@
 | 
			
		|||
import { ComponentStyle, usePropertyForm } from '@/components/DiyEditor/util'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 组件容器属性
 | 
			
		||||
 * 组件容器属性:目前右边部分
 | 
			
		||||
 * 用于包裹组件,为组件提供 背景、外边距、内边距、边框等样式
 | 
			
		||||
 */
 | 
			
		||||
defineOptions({ name: 'ComponentContainer' })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,16 +41,19 @@ import { componentConfigs } from '../components/mobile/index'
 | 
			
		|||
import { cloneDeep } from 'lodash-es'
 | 
			
		||||
import { DiyComponent, DiyComponentLibrary } from '@/components/DiyEditor/util'
 | 
			
		||||
 | 
			
		||||
/** 组件库 */
 | 
			
		||||
/** 组件库:目前左侧的【基础组件】、【图文组件】部分 */
 | 
			
		||||
defineOptions({ name: 'ComponentLibrary' })
 | 
			
		||||
 | 
			
		||||
// 组件列表
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  list: DiyComponentLibrary[]
 | 
			
		||||
}>()
 | 
			
		||||
// 组件分组
 | 
			
		||||
const groups = reactive<any[]>([])
 | 
			
		||||
// 展开的折叠面板
 | 
			
		||||
const extendGroups = reactive<string[]>([])
 | 
			
		||||
 | 
			
		||||
// 监听 list 属性,按照 DiyComponentLibrary 的 name 分组
 | 
			
		||||
watch(
 | 
			
		||||
  () => props.list,
 | 
			
		||||
  () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,11 +27,12 @@
 | 
			
		|||
        </el-tooltip>
 | 
			
		||||
      </el-button-group>
 | 
			
		||||
    </el-header>
 | 
			
		||||
 | 
			
		||||
    <!-- 中心区域 -->
 | 
			
		||||
    <el-container class="editor-container">
 | 
			
		||||
      <!-- 左侧:组件库 -->
 | 
			
		||||
      <!-- 左侧:组件库(ComponentLibrary) -->
 | 
			
		||||
      <ComponentLibrary ref="componentLibrary" :list="libs" v-if="libs && libs.length > 0" />
 | 
			
		||||
      <!-- 中心设计区域 -->
 | 
			
		||||
      <!-- 中心:设计区域(ComponentContainer) -->
 | 
			
		||||
      <div class="editor-center page-prop-area" @click="handlePageSelected">
 | 
			
		||||
        <!-- 手机顶部 -->
 | 
			
		||||
        <div class="editor-design-top">
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +133,7 @@
 | 
			
		|||
          </template>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <!-- 右侧属性面板 -->
 | 
			
		||||
      <!-- 右侧:属性面板(ComponentContainerProperty) -->
 | 
			
		||||
      <el-aside class="editor-right" width="350px" v-if="selectedComponent?.property">
 | 
			
		||||
        <el-card
 | 
			
		||||
          shadow="never"
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +161,7 @@
 | 
			
		|||
      </el-aside>
 | 
			
		||||
    </el-container>
 | 
			
		||||
  </el-container>
 | 
			
		||||
 | 
			
		||||
  <!-- 预览弹框 -->
 | 
			
		||||
  <Dialog v-model="previewDialogVisible" title="预览" width="700">
 | 
			
		||||
    <div class="flex justify-around">
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +233,7 @@ const props = defineProps({
 | 
			
		|||
})
 | 
			
		||||
 | 
			
		||||
// 监听传入的页面配置
 | 
			
		||||
// 解析出 pageConfigComponent 页面整体的配置,navigationBarComponent、pageComponents、tabBarComponent 页面上、中、下的配置
 | 
			
		||||
watch(
 | 
			
		||||
  () => props.modelValue,
 | 
			
		||||
  () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -251,6 +254,7 @@ watch(
 | 
			
		|||
    immediate: true
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 保存
 | 
			
		||||
const handleSave = () => {
 | 
			
		||||
  const pageConfig = {
 | 
			
		||||
| 
						 | 
				
			
			@ -303,7 +307,7 @@ const handleTabBarSelected = () => {
 | 
			
		|||
  handleComponentSelected(unref(tabBarComponent))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 组件变动
 | 
			
		||||
// 组件变动(拖拽)
 | 
			
		||||
const handleComponentChange = (dragEvent: any) => {
 | 
			
		||||
  // 新增,即从组件库拖拽添加组件
 | 
			
		||||
  if (dragEvent.added) {
 | 
			
		||||
| 
						 | 
				
			
			@ -327,19 +331,21 @@ const swapComponent = (oldIndex: number, newIndex: number) => {
 | 
			
		|||
  selectedComponentIndex.value = newIndex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 移动组件 */
 | 
			
		||||
/** 移动组件(上移、下移) */
 | 
			
		||||
const handleMoveComponent = (index: number, direction: number) => {
 | 
			
		||||
  const newIndex = index + direction
 | 
			
		||||
  if (newIndex < 0 || newIndex >= pageComponents.value.length) return
 | 
			
		||||
 | 
			
		||||
  swapComponent(index, newIndex)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 复制组件 */
 | 
			
		||||
const handleCopyComponent = (index: number) => {
 | 
			
		||||
  const component = cloneDeep(pageComponents.value[index])
 | 
			
		||||
  component.uid = new Date().getTime()
 | 
			
		||||
  pageComponents.value.splice(index + 1, 0, component)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 删除组件
 | 
			
		||||
 * @param index 当前组件index
 | 
			
		||||
| 
						 | 
				
			
			@ -371,6 +377,7 @@ const handleReset = () => {
 | 
			
		|||
  if (reload) reload()
 | 
			
		||||
  emits('reset')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 预览
 | 
			
		||||
const previewDialogVisible = ref(false)
 | 
			
		||||
const handlePreview = () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -388,10 +395,12 @@ const setDefaultSelectedComponent = () => {
 | 
			
		|||
    selectedComponent.value = unref(tabBarComponent)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
  () => [props.showPageConfig, props.showNavigationBar, props.showTabBar],
 | 
			
		||||
  () => setDefaultSelectedComponent()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
onMounted(() => setDefaultSelectedComponent())
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -472,7 +472,9 @@ const remainingRouter: AppRouteRecordRaw[] = [
 | 
			
		|||
        meta: {
 | 
			
		||||
          title: '模板装修',
 | 
			
		||||
          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')
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			@ -482,7 +484,9 @@ const remainingRouter: AppRouteRecordRaw[] = [
 | 
			
		|||
        meta: {
 | 
			
		||||
          title: '页面装修',
 | 
			
		||||
          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')
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@ const getPageDetail = async (id: any) => {
 | 
			
		|||
    formLoading.value = false
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 提交表单
 | 
			
		||||
const submitForm = async () => {
 | 
			
		||||
  // 校验表单
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue