2
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user