Files
timeTableFix/src/App.vue
zikai a49a725950 refactor: App.vue 样式隔离,使其可作为组件被嵌入
- 全局重置(* / body)抽到 src/styles/global.css,仅独立 app 的 main.js 加载
- App.vue <style> 改 scoped,根及内部类名加 ttf- 前缀,避免与宿主冲突
- 根 class app -> ttf-app,min-height 改为填满容器以适配嵌入
- 加 defineOptions({ name: 'timetable' }) 供宿主 KeepAlive 匹配
- README 嵌入说明改为构建期组件集成 + git submodule
- 不影响独立运行:npm test 42 项通过,npm run build 通过
2026-07-23 02:48:58 +00:00

118 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
// 组件名与 mainPage 模块 id 一致,供 <KeepAlive :include> 按 id 精确匹配。
// 作为独立 app 运行时该名不影响行为。
defineOptions({ name: 'timetable' })
import { useCalendar } from './composables/useCalendar.js'
import DropZone from './components/DropZone.vue'
import HeaderBar from './components/HeaderBar.vue'
import EventList from './components/EventList.vue'
import EventDetail from './components/EventDetail.vue'
import MonthPreview from './components/MonthPreview.vue'
import WeekPreview from './components/WeekPreview.vue'
const { isLoaded, state, setViewMode } = useCalendar()
</script>
<template>
<div class="ttf-app">
<header class="ttf-header">
<div class="ttf-header-left">
<h1>ICS 日程整理器</h1>
<div v-if="isLoaded" class="ttf-view-switcher">
<button
:class="{ active: state.viewMode === 'edit' }"
@click="setViewMode('edit')"
>编辑</button>
<button
:class="{ active: state.viewMode === 'month' }"
@click="setViewMode('month')"
>月预览</button>
<button
:class="{ active: state.viewMode === 'week' }"
@click="setViewMode('week')"
>周预览</button>
</div>
</div>
<HeaderBar />
</header>
<main class="ttf-main">
<DropZone v-if="!isLoaded" />
<template v-else>
<EventList v-if="state.viewMode === 'edit'" />
<div class="ttf-detail-area">
<EventDetail v-if="state.viewMode === 'edit'" />
<MonthPreview v-else-if="state.viewMode === 'month'" />
<WeekPreview v-else-if="state.viewMode === 'week'" />
</div>
</template>
</main>
</div>
</template>
<style scoped>
/* scoped样式仅作用于本组件作为组件被嵌入时不污染宿主。
全局重置(* / body已移至 src/styles/global.css仅独立 app 加载。 */
.ttf-app {
display: flex;
flex-direction: column;
/* 适配嵌入:填满宿主 <main> 区域;独立 app 下 body 仍提供背景 */
min-height: 0;
height: 100%;
}
.ttf-header {
background: #2c3e50;
color: #fff;
padding: 14px 24px;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
.ttf-header-left {
display: flex;
align-items: center;
gap: 24px;
}
.ttf-header h1 { font-size: 18px; font-weight: 600; white-space: nowrap; }
.ttf-view-switcher {
display: flex;
background: #1a252f;
border-radius: 6px;
overflow: hidden;
}
.ttf-view-switcher button {
background: transparent;
color: #bdc3c7;
border: none;
padding: 6px 16px;
font-size: 13px;
cursor: pointer;
transition: all 0.15s;
}
.ttf-view-switcher button:hover { color: #fff; }
.ttf-view-switcher button.active {
background: #3498db;
color: #fff;
}
.ttf-main { flex: 1; display: flex; overflow: hidden; min-height: 0; }
.ttf-detail-area { flex: 1; overflow-y: auto; }
/* 移动端适配 */
@media (max-width: 768px) {
.ttf-header {
flex-direction: column;
gap: 10px;
padding: 10px 12px;
}
.ttf-header-left {
width: 100%;
justify-content: space-between;
gap: 12px;
}
.ttf-header h1 { font-size: 15px; }
.ttf-view-switcher button { padding: 5px 10px; font-size: 12px; }
.ttf-main { flex-direction: column; }
}
</style>