hookehuyr

refactor(layout): 移除遗留布局目录并更新相关文档

- 删除 src/layouts/AppLayout.vue,统一使用 src/components/layout/AppLayout.vue
- 从组件类型声明中移除 VanTabbar 和 VanTabbarItem
- 更新 myClassPage.vue 导入以使用新的布局路径
- 同步更新 README、COMPONENTS 和 VUE_CODE_STYLE_GUIDE 中的文档说明
...@@ -53,10 +53,9 @@ src/ ...@@ -53,10 +53,9 @@ src/
53 53
54 - 文档与代码存在不一致:README/CLAUDE 中的组件目录、路径描述与实际目录不一致 54 - 文档与代码存在不一致:README/CLAUDE 中的组件目录、路径描述与实际目录不一致
55 - 依赖与工程规范不够统一:同时存在 pnpm/yarn/npm 的 lock 文件,容易引起依赖漂移 55 - 依赖与工程规范不够统一:同时存在 pnpm/yarn/npm 的 lock 文件,容易引起依赖漂移
56 -- 构建产物体积偏大:首屏 main chunk 已压到 500kB 内;仍有 video.js / pdf.js 等功能性依赖 chunk 超 500kB,但仅在对应功能触发时按需加载
57 - 状态来源较多:localStorage + contexts + axios 默认头并存,一致性风险偏高 56 - 状态来源较多:localStorage + contexts + axios 默认头并存,一致性风险偏高
58 - 全局屏蔽 warnHandler:[/src/main.js](file:///Users/huyirui/program/itomix/git/mlaj/src/main.js) 会吞掉 Vue 警告,可能掩盖潜在问题 57 - 全局屏蔽 warnHandler:[/src/main.js](file:///Users/huyirui/program/itomix/git/mlaj/src/main.js) 会吞掉 Vue 警告,可能掩盖潜在问题
59 -- 目录存在历史遗留:[/src/layouts](file:///Users/huyirui/program/itomix/git/mlaj/src/layouts)[/src/components/layout](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout) 并存,建议后续清理归一 58 +- 布局目录已归一:统一使用 [/src/components/layout](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout),已移除 /src/layouts
60 59
61 ## 文档索引 60 ## 文档索引
62 61
......
...@@ -204,7 +204,7 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为 ...@@ -204,7 +204,7 @@ Vue 官方建议在 SFC + Composition API 场景使用 `<script setup>`,因为
204 4) 清理“重复/并存”的实现:避免同名组件在不同目录各自演进 204 4) 清理“重复/并存”的实现:避免同名组件在不同目录各自演进
205 205
206 - 目标:减少认知负担与误用风险(例如存在两个 `AppLayout` 206 - 目标:减少认知负担与误用风险(例如存在两个 `AppLayout`
207 -- 涉及文件:[layouts/AppLayout.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/layouts/AppLayout.vue)[components/layout/AppLayout.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout/AppLayout.vue) 207 +- 涉及文件:[AppLayout.vue](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout/AppLayout.vue)(已完成归一,移除 /src/layouts)
208 208
209 5) 降低“语法形态”混用成本:能不用 JSX 就别用 209 5) 降低“语法形态”混用成本:能不用 JSX 就别用
210 210
......
...@@ -22,4 +22,4 @@ ...@@ -22,4 +22,4 @@
22 22
23 ## 备注 23 ## 备注
24 24
25 -- 历史遗留目录:[/src/layouts](file:///Users/huyirui/program/itomix/git/mlaj/src/layouts)[/src/components/layout](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout) 并存,建议后续合并归一 25 +- 布局目录已归一:统一使用 [/src/components/layout](file:///Users/huyirui/program/itomix/git/mlaj/src/components/layout),已移除 /src/layouts
......
...@@ -95,8 +95,6 @@ declare module 'vue' { ...@@ -95,8 +95,6 @@ declare module 'vue' {
95 VanSwipe: typeof import('vant/es')['Swipe'] 95 VanSwipe: typeof import('vant/es')['Swipe']
96 VanSwipeItem: typeof import('vant/es')['SwipeItem'] 96 VanSwipeItem: typeof import('vant/es')['SwipeItem']
97 VanTab: typeof import('vant/es')['Tab'] 97 VanTab: typeof import('vant/es')['Tab']
98 - VanTabbar: typeof import('vant/es')['Tabbar']
99 - VanTabbarItem: typeof import('vant/es')['TabbarItem']
100 VanTabs: typeof import('vant/es')['Tabs'] 98 VanTabs: typeof import('vant/es')['Tabs']
101 VanTag: typeof import('vant/es')['Tag'] 99 VanTag: typeof import('vant/es')['Tag']
102 VanTimePicker: typeof import('vant/es')['TimePicker'] 100 VanTimePicker: typeof import('vant/es')['TimePicker']
......
1 -<!-- src/layouts/AppLayout.vue -->
2 -<template>
3 - <div class="app-layout">
4 - <!-- Header -->
5 - <header class="app-header" v-if="hasTitle">
6 - <div v-if="showBack" class="header-back" @click="goBack">
7 - <van-icon name="arrow-left" size="20" />
8 - </div>
9 - <h1 class="header-title">{{ title }}</h1>
10 - <div class="header-right">
11 - <slot name="header-right"></slot>
12 - </div>
13 - </header>
14 -
15 - <!-- Main Content -->
16 - <main class="app-content" :class="{ 'has-bottom-nav': showBottomNav, 'no-header': !hasTitle }">
17 - <slot></slot>
18 - </main>
19 -
20 - <!-- Bottom Navigation -->
21 - <van-tabbar v-if="showBottomNav" route safe-area-inset-bottom>
22 - <van-tabbar-item to="/home" icon="home-o">首页</van-tabbar-item>
23 - <van-tabbar-item to="/courses" icon="orders-o">课程</van-tabbar-item>
24 - <van-tabbar-item to="/activities" icon="friends-o">活动</van-tabbar-item>
25 - <van-tabbar-item to="/community" icon="chat-o">社区</van-tabbar-item>
26 - <van-tabbar-item to="/profile" icon="user-o">我的</van-tabbar-item>
27 - </van-tabbar>
28 - </div>
29 -</template>
30 -
31 -<script>
32 -import { ref, onMounted, computed } from 'vue'
33 -import { useRouter, useRoute } from 'vue-router'
34 -
35 -export default {
36 - name: 'AppLayout',
37 - props: {
38 - title: {
39 - type: String,
40 - default: '美乐爱觉教育'
41 - },
42 - showBack: {
43 - type: Boolean,
44 - default: false
45 - },
46 - showBottomNav: {
47 - type: Boolean,
48 - default: true
49 - },
50 - hasTitle: {
51 - type: Boolean,
52 - default: true
53 - },
54 - },
55 - setup(props) {
56 - const router = useRouter()
57 - const route = useRoute()
58 -
59 - const goBack = () => {
60 - if (window.history.length > 1) {
61 - router.back()
62 - } else {
63 - router.push('/')
64 - }
65 - }
66 -
67 - return {
68 - goBack,
69 - }
70 - }
71 -}
72 -</script>
73 -
74 -<style scoped>
75 -.app-layout {
76 - display: flex;
77 - flex-direction: column;
78 - min-height: 100vh;
79 - background-color: var(--background-color);
80 -}
81 -
82 -.app-header {
83 - position: sticky;
84 - top: 0;
85 - z-index: 100;
86 - display: flex;
87 - align-items: center;
88 - justify-content: center;
89 - height: 46px;
90 - padding: 0 16px;
91 - background-color: var(--white);
92 - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
93 -}
94 -
95 -.header-back {
96 - position: absolute;
97 - left: 16px;
98 - display: flex;
99 - align-items: center;
100 - justify-content: center;
101 -}
102 -
103 -.header-title {
104 - font-size: 18px;
105 - font-weight: 600;
106 - margin: 0;
107 -}
108 -
109 -.header-right {
110 - position: absolute;
111 - right: 16px;
112 - display: flex;
113 - align-items: center;
114 -}
115 -
116 -.app-content {
117 - flex: 1;
118 - overflow-y: auto;
119 - padding-bottom: 20px;
120 - -webkit-overflow-scrolling: touch;
121 -}
122 -
123 -.app-content.has-bottom-nav {
124 - padding-bottom: 50px;
125 -}
126 -
127 -.app-content.no-header {
128 - padding-top: 0;
129 -}
130 -</style>
...@@ -166,8 +166,7 @@ ...@@ -166,8 +166,7 @@
166 166
167 <script setup> 167 <script setup>
168 import { ref, computed, onMounted, onUnmounted } from 'vue' 168 import { ref, computed, onMounted, onUnmounted } from 'vue'
169 -import { useRouter } from 'vue-router' 169 +import { useRouter, useRoute } from 'vue-router'
170 -import AppLayout from '@/layouts/AppLayout.vue'
171 import { useTitle } from '@vueuse/core'; 170 import { useTitle } from '@vueuse/core';
172 import { useAuth } from '@/contexts/auth' 171 import { useAuth } from '@/contexts/auth'
173 import CourseGroupCascader from '@/components/courses/CourseGroupCascader.vue' 172 import CourseGroupCascader from '@/components/courses/CourseGroupCascader.vue'
......