120 lines
2.5 KiB
Vue
120 lines
2.5 KiB
Vue
<script setup lang="ts">
|
||
import { defineAsyncComponent, computed, watch } from 'vue'
|
||
import { useVueFileStore } from '../../stores/vueFileStore'
|
||
import InteractiveWrapper from './InteractiveWrapper.vue'
|
||
import config from './index.json'
|
||
|
||
const vueFileStore = useVueFileStore()
|
||
|
||
// 扫描所有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="file-info" v-if="vueFileStore.selectedFilePath">
|
||
📄 {{ vueFileStore.selectedFileName }}
|
||
</span>
|
||
</div>
|
||
<div class="center-body">
|
||
<!-- 动态渲染选中的Vue页面(使用InteractiveWrapper注入交互事件) -->
|
||
<div v-if="selectedPageComponent" class="page-preview">
|
||
<InteractiveWrapper :component="selectedPageComponent" />
|
||
</div>
|
||
|
||
<!-- 空状态 -->
|
||
<div v-else class="empty-tip">
|
||
<div class="empty-icon">🎨</div>
|
||
<div>暂无内容</div>
|
||
<div class="empty-hint">
|
||
点击“页面管理”选择Vue页面开始设计
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.design-center {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
background: #1e1e1e;
|
||
}
|
||
|
||
.center-header {
|
||
padding: 8px 12px;
|
||
background: #2d2d2d;
|
||
border-bottom: 1px solid #3c3c3c;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.title {
|
||
color: #cccccc;
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.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;
|
||
}
|
||
|
||
.empty-tip {
|
||
color: #666666;
|
||
text-align: center;
|
||
padding: 40px 20px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.empty-icon {
|
||
font-size: 40px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.empty-hint {
|
||
font-size: 11px;
|
||
margin-top: 8px;
|
||
color: #555555;
|
||
}
|
||
</style>
|