This commit is contained in:
wfz
2025-12-21 20:58:34 +08:00
parent 83bafa4e1e
commit c6077ff2ad
22 changed files with 2004 additions and 33 deletions

View File

@@ -1,9 +1,11 @@
<script setup lang="ts">
import { defineAsyncComponent, markRaw } from 'vue'
import { defineAsyncComponent, markRaw, computed, watch } from 'vue'
import { useDesignStore } from '../../stores/designStore'
import { useVueFileStore } from '../../stores/vueFileStore'
import config from './index.json'
const designStore = useDesignStore()
const vueFileStore = useVueFileStore()
// 自动扫描所有设计组件eager 模式确保同步加载)
const designComponentModules = import.meta.glob('../../designComponents/*/index.vue', { eager: true })
@@ -33,39 +35,78 @@ const handleRemove = (instanceId: string, event: Event) => {
event.stopPropagation()
designStore.removeComponent(instanceId)
}
// 扫描所有views目录下的Vue文件
const viewModules = import.meta.glob('../../../views/**/*.vue')
// 当前选中的Vue页面组件
const selectedPageComponent = computed(() => {
if (!vueFileStore.selectedFilePath) {
return null
}
// 动态加载选中的组件
const loader = viewModules[vueFileStore.selectedFilePath]
if (loader) {
return defineAsyncComponent(loader as any)
}
return null
})
// 监听选中文件变化
watch(() => vueFileStore.selectedFilePath, (newPath) => {
console.log('设计中心:选中的文件路径变化', newPath)
})
</script>
<template>
<div class="design-center">
<div class="center-header">
<span class="title">{{ config.name }}</span>
<span class="count">{{ designStore.components.length }} 个实例</span>
<span class="count" v-if="!vueFileStore.selectedFilePath">
{{ designStore.components.length }} 个实例
</span>
<span class="file-info" v-else>
📄 {{ vueFileStore.selectedFileName }}
</span>
</div>
<div class="center-body">
<div
v-for="instance in designStore.components"
:key="instance.id"
class="component-row"
:class="{ selected: designStore.selectedId === instance.id }"
@click="handleSelect(instance.id)"
>
<div class="component-label">
<span class="component-name">{{ instance.name }}</span>
<button class="remove-btn" @click="handleRemove(instance.id, $event)">×</button>
</div>
<div class="component-preview">
<component
v-if="getComponent(instance.componentId)"
:is="getComponent(instance.componentId)"
v-bind="instance.props"
/>
<!-- 动态渲染选中的Vue页面 -->
<div v-if="selectedPageComponent" class="page-preview">
<component :is="selectedPageComponent" />
</div>
<!-- 原有的设计组件实例列表 -->
<div v-else-if="designStore.components.length > 0" class="component-list">
<div
v-for="instance in designStore.components"
:key="instance.id"
class="component-row"
:class="{ selected: designStore.selectedId === instance.id }"
@click="handleSelect(instance.id)"
>
<div class="component-label">
<span class="component-name">{{ instance.name }}</span>
<button class="remove-btn" @click="handleRemove(instance.id, $event)">×</button>
</div>
<div class="component-preview">
<component
v-if="getComponent(instance.componentId)"
:is="getComponent(instance.componentId)"
v-bind="instance.props"
/>
</div>
</div>
</div>
<div v-if="designStore.components.length === 0" class="empty-tip">
<!-- 空状态 -->
<div v-else class="empty-tip">
<div class="empty-icon">🎨</div>
<div>暂无设计组件</div>
<div class="empty-hint">从左侧列表点击添加</div>
<div>暂无内容</div>
<div class="empty-hint">
点击页面管理选择Vue页面或从左侧列表添加设计组件
</div>
</div>
</div>
</div>
@@ -99,12 +140,32 @@ const handleRemove = (instanceId: string, event: Event) => {
font-size: 11px;
}
.file-info {
color: #4fc3f7;
font-size: 12px;
font-weight: 500;
}
.center-body {
flex: 1;
padding: 12px;
overflow: auto;
}
.page-preview {
width: 100%;
height: 100%;
background: white;
border-radius: 8px;
overflow: auto;
}
.component-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.component-row {
margin-bottom: 12px;
border-radius: 6px;