refactor(layout): 移除遗留布局目录并更新相关文档
- 删除 src/layouts/AppLayout.vue,统一使用 src/components/layout/AppLayout.vue - 从组件类型声明中移除 VanTabbar 和 VanTabbarItem - 更新 myClassPage.vue 导入以使用新的布局路径 - 同步更新 README、COMPONENTS 和 VUE_CODE_STYLE_GUIDE 中的文档说明
Showing
6 changed files
with
4 additions
and
138 deletions
| ... | @@ -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'] | ... | ... |
src/layouts/AppLayout.vue
deleted
100644 → 0
| 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' | ... | ... |
-
Please register or login to post a comment