Files
medical-mall/docs/admin/CRMEB_UVUE_MIGRATION_GUIDE.md
2026-02-02 20:07:37 +08:00

1276 lines
27 KiB
Markdown
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.
# CRMEB 页面设计规范与 Uni-App-X UVue 复刻指南
## 📋 目录
1. [CRMEB 项目架构分析](#crmeb-项目架构分析)
2. [页面布局模式](#页面布局模式)
3. [样式系统设计](#样式系统设计)
4. [组件设计规范](#组件设计规范)
5. [工程化配置](#工程化配置)
6. [UVue 复刻方案](#uvue-复刻方案)
7. [迁移检查清单](#迁移检查清单)
---
## CRMEB 项目架构分析
### 1. 项目结构概览
```
CRMEB/template/admin/
├── src/
│ ├── layout/ # 布局系统
│ │ ├── index.vue # 主布局容器(支持多种布局模式)
│ │ ├── main/ # 主要布局模式
│ │ │ ├── defaults.vue # 默认布局
│ │ │ ├── classic.vue # 经典布局
│ │ │ ├── transverse.vue # 横向布局
│ │ │ └── columns.vue # 分栏布局
│ │ ├── navBars/ # 导航栏系统
│ │ │ ├── breadcrumb/ # 面包屑
│ │ │ └── tagsView/ # 标签页
│ │ ├── navMenu/ # 侧边栏菜单
│ │ ├── footer/ # 页脚
│ │ └── component/ # 布局相关组件
│ ├── components/ # 全局可复用组件60+
│ │ ├── cards/ # 卡片组件
│ │ ├── from/ # 表单相关
│ │ ├── searchFrom/ # 搜索表单
│ │ └── ...
│ ├── pages/ # 页面模块16个大类
│ │ ├── account/ # 账户管理
│ │ ├── agent/ # 代理管理
│ │ ├── app/ # APP管理
│ │ ├── cms/ # CMS内容
│ │ ├── finance/ # 财务
│ │ ├── order/ # 订单
│ │ ├── product/ # 商品
│ │ ├── system/ # 系统设置
│ │ ├── user/ # 用户管理
│ │ └── ...
│ ├── styles/ # 全局样式
│ ├── router/ # 路由配置
│ ├── store/ # 状态管理Vuex
│ ├── utils/ # 工具函数
│ └── ...
├── package.json # 项目依赖Vue 2
├── vue.config.js # Webpack 配置
├── .prettierrc.js # 代码格式化规则
└── babel.config.js # Babel 配置
```
### 2. 核心设计特点
#### 2.1 多布局支持
CRMEB 支持 4 种布局模式:
- **Defaults**: 侧边栏 + 顶部菜单 + 内容区
- **Classic**: 经典布局(左菜单 + 内容)
- **Transverse**: 顶部菜单 + 内容
- **Columns**: 三栏布局(侧菜单 + 侧栏 + 内容)
#### 2.2 标签页系统
- 每个打开的页面都生成一个标签
- 支持标签页关闭、固定、刷新
- 与路由历史联动
#### 2.3 面包屑导航
- 动态生成,根据路由元信息
- 支持多级导航回溯
#### 2.4 响应式设计
- 自动监听窗口大小
- < 1000px 时自动切换移动端布局
- 侧边栏自动收起
---
## 页面布局模式
### CRMEB 的四种布局
#### 模式 1: Defaults默认布局 - 最常用)
```
┌─────────────────────────────────────────┐
│ Logo │ Breadcrumb │ Tags │ User │ ← NavBars
├─────────┼─────────────────────────────────┤
│ Menu │ │
│ │ Content Area │
│ │ (Page Components) │
│ │ │
├─────────┴─────────────────────────────────┤
│ Footer │
└─────────────────────────────────────────┘
```
**特点**:
- 左侧固定菜单栏
- 顶部面包屑 + 标签页
- 主内容区占据剩余空间
#### 模式 2: Classic经典布局
```
┌─────────────────────────────────────────┐
│ Logo │ Breadcrumb │ Tags │ User Settings │ ← NavBars
├──────┴─────────────────────────────────────┤
│ Menu │ Content Area │
│ │ (Page Components) │
│ │ │
├──────┴─────────────────────────────────────┤
│ Footer │
└─────────────────────────────────────────────┘
```
#### 模式 3: Transverse横向菜单
```
┌────────────────────────────────────────┐
│ Logo │ Menu 1 │ Menu 2 │ ... │ Settings│ ← Top Menu
├────────────────────────────────────────┤
│ Breadcrumb │ Tags │ Actions │
├────────────────────────────────────────┤
│ │
│ Content Area │
│ (Page Components) │
│ │
└────────────────────────────────────────┘
```
#### 模式 4: Columns三栏布局
```
┌──────────────────────────────────────────┐
│ NavBars (Breadcrumb + Tags) │
├─────────┬──────────┬──────────────────────┤
│ Menu │ SubMenu │ Content Area │
│ │ │ (Page Components) │
│ │ │ │
└─────────┴──────────┴──────────────────────┘
```
---
## 样式系统设计
### 1. 全局样式架构
```scss
styles/
common.scss # 通用样式重置基础类名
variables.scss # CSS 变量主题颜色
animate.scss # 动画库
element-ui.scss # Element UI 主题覆盖
index.scss # 主入口文件
```
### 2. 颜色系统
CRMEB 使用标准设计系统颜色:
- **主颜色**: `#1890ff`(蓝色)
- **成功**: `#52c41a`(绿色)
- **警告**: `#faad14`(黄色)
- **错误**: `#ff4d4f`(红色)
- **边框**: `#d9d9d9`(灰色)
- **文字**: `#000000` / `#666666` / `#999999`
### 3. 间距系统
```scss
$space-xs: 4px;
$space-sm: 8px;
$space: 12px;
$space-md: 16px;
$space-lg: 24px;
$space-xl: 32px;
```
### 4. 圆角系统
```scss
$radius-xs: 2px;
$radius-sm: 4px;
$radius: 6px;
$radius-lg: 8px;
$radius-xl: 12px;
```
### 5. 阴影系统
```scss
$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.06);
$shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
```
---
## 组件设计规范
### 1. 组件命名规范
```
常用组件类型:
- Cards/ # 卡片展示(数据统计卡、信息卡)
- Form/ # 表单相关(表单控件、表单验证)
- List/ # 列表显示(表格、数据列表)
- Modal/ # 模态框(确认框、详情框)
- Table/ # 表格组件(支持排序、分页、筛选)
- Upload/ # 上传组件(图片、视频、文件)
- Search/ # 搜索组件(高级搜索、快速搜索)
```
### 2. 常用组件库
CRMEB 使用 Element UI 作为基础组件库:
- `el-button` - 按钮
- `el-input` - 输入框
- `el-select` - 选择器
- `el-table` - 表格
- `el-form` - 表单
- `el-dialog` - 对话框
- `el-tree` - 树形控件
- `el-pagination` - 分页
### 3. 页面组件结构
```vue
<template>
<div class="page-container">
<!-- 页面标题 / 操作栏 -->
<div class="page-header">
<h1>{{ pageTitle }}</h1>
<div class="page-actions">
<el-button type="primary">新增</el-button>
<el-button>导出</el-button>
</div>
</div>
<!-- 搜索表单 -->
<div class="search-container">
<SearchForm @search="handleSearch" />
</div>
<!-- 列表 / 内容区 -->
<div class="content-container">
<el-table :data="tableData" />
</div>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination @current-change="handlePageChange" />
</div>
</div>
</template>
<script>
export default {
name: "PageName",
components: {
SearchForm: () => import("@/components/searchFrom/index"),
},
data() {
return {
pageTitle: "页面标题",
tableData: [],
};
},
};
</script>
<style scoped lang="scss">
.page-container {
padding: 20px;
}
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h1 {
font-size: 20px;
font-weight: 600;
}
}
.search-container {
margin-bottom: 20px;
}
.content-container {
background: #fff;
border-radius: 4px;
padding: 20px;
margin-bottom: 20px;
}
.pagination-container {
display: flex;
justify-content: flex-end;
}
</style>
```
---
## 工程化配置
### 1. 构建工具配置
**vue.config.js** (Webpack):
```javascript
module.exports = {
productionSourceMap: false,
configureWebpack: {
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
},
chainWebpack: (config) => {
// 优化大文件分割
config.optimization.splitChunks({
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "chunk-vendors",
priority: 10,
},
common: {
minChunks: 2,
priority: 5,
reuseExistingChunk: true,
},
},
});
},
};
```
### 2. 代码格式化配置
**.prettierrc.js**:
```javascript
module.exports = {
printWidth: 100,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: "es5",
bracketSpacing: true,
arrowParens: "always",
};
```
### 3. ESLint 配置
**.eslintrc.js**:
```javascript
module.exports = {
root: true,
env: {
node: true,
browser: true,
es2021: true,
},
extends: ["plugin:vue/essential", "eslint:recommended"],
parserOptions: {
parser: "babel-eslint",
ecmaVersion: 2020,
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
};
```
### 4. Babel 配置
**babel.config.js**:
```javascript
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
plugins: [],
};
```
---
## UVue 复刻方案
### 1. 布局系统复刻
#### 1.1 AdminLayout 增强版
**layouts/admin/AdminLayout.uvue** - 支持多种布局:
```uvue
<template>
<view class="admin-layout" :class="layoutClass">
<!-- 模式1: Defaults默认布局 -->
<template v-if="layoutMode === 'defaults'">
<AdminAside :collapsed="isCollapsed" @toggle="toggleCollapse" />
<view class="admin-main-defaults">
<AdminNavBar :breadcrumb="breadcrumb" />
<AdminTagsView :tabs="tabs" />
<view class="admin-content-defaults">
<slot></slot>
</view>
<AdminFooter />
</view>
</template>
<!-- 模式2: Classic经典布局 -->
<template v-else-if="layoutMode === 'classic'">
<view class="admin-sidebar-classic">
<AdminAside :collapsed="isCollapsed" @toggle="toggleCollapse" />
</view>
<view class="admin-main-classic">
<AdminNavBar />
<view class="admin-content-classic">
<slot></slot>
</view>
</view>
</template>
<!-- 模式3: Columns三栏布局 -->
<template v-else-if="layoutMode === 'columns'">
<AdminAside :collapsed="isCollapsed" @toggle="toggleCollapse" />
<AdminSubSider :collapsed="isSubCollapsed" @toggle="toggleSubCollapse" />
<view class="admin-main-columns">
<AdminNavBar />
<view class="admin-content-columns">
<slot></slot>
</view>
</view>
</template>
</view>
</template>
<script setup lang="uts">
import { ref, computed, watch, onMounted, provide } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import AdminAside from './components/AdminAside.uvue'
import AdminSubSider from './components/AdminSubSider.uvue'
import AdminNavBar from './components/AdminNavBar.uvue'
import AdminTagsView from './components/AdminTagsView.uvue'
import AdminFooter from './components/AdminFooter.uvue'
// Props
interface AdminLayoutProps {
currentPage: string
layoutMode?: 'defaults' | 'classic' | 'columns'
}
const props = withDefaults(defineProps<AdminLayoutProps>(), {
layoutMode: 'defaults'
})
// State
const isCollapsed = ref(false)
const isSubCollapsed = ref(false)
const tabs = ref([])
const breadcrumb = ref('')
// Computed
const layoutClass = computed(() => `layout-${props.layoutMode}`)
// Methods
const toggleCollapse = () => {
isCollapsed.value = !isCollapsed.value
}
const toggleSubCollapse = () => {
isSubCollapsed.value = !isSubCollapsed.value
}
// Provide to children
provide('layoutMode', props.layoutMode)
provide('isCollapsed', isCollapsed)
</script>
<style scoped lang="uts">
.admin-layout {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background: #f5f5f5;
}
/* Defaults 布局样式 */
.layout-defaults {
flex-direction: row;
}
.admin-main-defaults {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.admin-content-defaults {
flex: 1;
overflow-y: auto;
padding: 20px;
}
/* Classic 布局样式 */
.layout-classic {
flex-direction: row;
}
.admin-sidebar-classic {
width: 200px;
height: 100vh;
overflow: hidden;
}
.admin-main-classic {
flex: 1;
display: flex;
flex-direction: column;
}
.admin-content-classic {
flex: 1;
overflow-y: auto;
padding: 20px;
}
/* Columns 布局样式 */
.layout-columns {
flex-direction: row;
}
.admin-main-columns {
flex: 1;
display: flex;
flex-direction: column;
}
.admin-content-columns {
flex: 1;
overflow-y: auto;
padding: 20px;
}
</style>
```
### 2. 样式系统复刻
#### 2.1 主样式文件
**uni.scss** - 全局 SCSS 变量:
```scss
// 颜色系统
$primary-color: #1890ff;
$success-color: #52c41a;
$warning-color: #faad14;
$error-color: #ff4d4f;
$info-color: #1890ff;
$text-primary: #000000;
$text-secondary: #666666;
$text-disabled: #999999;
$border-color: #d9d9d9;
$background-color: #f5f5f5;
// 间距系统
$space-xs: 4px;
$space-sm: 8px;
$space: 12px;
$space-md: 16px;
$space-lg: 24px;
$space-xl: 32px;
// 圆角系统
$radius-xs: 2px;
$radius-sm: 4px;
$radius: 6px;
$radius-lg: 8px;
$radius-xl: 12px;
// 阴影系统
$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.06);
$shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
$shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
// 字体大小
$font-size-xs: 12px;
$font-size-sm: 13px;
$font-size: 14px;
$font-size-md: 16px;
$font-size-lg: 18px;
$font-size-xl: 20px;
// 行高
$line-height-xs: 1.2;
$line-height-sm: 1.4;
$line-height: 1.6;
$line-height-lg: 1.8;
// 过渡动画
$transition-duration: 0.3s;
$transition-timing: cubic-bezier(0.645, 0.045, 0.355, 1);
```
#### 2.2 通用样式类
**styles/common.scss** - 常用工具类:
```scss
// 布局相关
.flex {
display: flex;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-col {
display: flex;
flex-direction: column;
}
// 间距相关
.m-xs {
margin: $space-xs;
}
.m-sm {
margin: $space-sm;
}
.m {
margin: $space;
}
.m-md {
margin: $space-md;
}
.m-lg {
margin: $space-lg;
}
.m-xl {
margin: $space-xl;
}
.p-xs {
padding: $space-xs;
}
.p-sm {
padding: $space-sm;
}
.p {
padding: $space;
}
.p-md {
padding: $space-md;
}
.p-lg {
padding: $space-lg;
}
.p-xl {
padding: $space-xl;
}
// 文字相关
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-primary {
color: $text-primary;
}
.text-secondary {
color: $text-secondary;
}
.text-disabled {
color: $text-disabled;
}
.text-xs {
font-size: $font-size-xs;
}
.text-sm {
font-size: $font-size-sm;
}
.text {
font-size: $font-size;
}
.text-md {
font-size: $font-size-md;
}
.text-lg {
font-size: $font-size-lg;
}
// 显示/隐藏
.hidden {
display: none;
}
.block {
display: block;
}
.inline-block {
display: inline-block;
}
// 溢出处理
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.line-clamp-2 {
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
// 边框
.border {
border: 1px solid $border-color;
}
.border-top {
border-top: 1px solid $border-color;
}
.border-bottom {
border-bottom: 1px solid $border-color;
}
.border-left {
border-left: 1px solid $border-color;
}
.border-right {
border-right: 1px solid $border-color;
}
// 圆角
.rounded {
border-radius: $radius;
}
.rounded-sm {
border-radius: $radius-sm;
}
.rounded-lg {
border-radius: $radius-lg;
}
// 阴影
.shadow-sm {
box-shadow: $shadow-sm;
}
.shadow {
box-shadow: $shadow;
}
.shadow-lg {
box-shadow: $shadow-lg;
}
// 背景色
.bg-white {
background-color: #ffffff;
}
.bg-light {
background-color: $background-color;
}
.bg-primary {
background-color: $primary-color;
}
// 透明度
.opacity-50 {
opacity: 0.5;
}
.opacity-75 {
opacity: 0.75;
}
```
### 3. 页面模板复刻
#### 3.1 标准列表页面
**pages/mall/admin/template/ListPage.uvue**
```uvue
<template>
<AdminLayout :currentPage="currentPage">
<view class="list-page">
<!-- 页面标题和操作栏 -->
<view class="page-header flex-between">
<text class="page-title">{{ pageTitle }}</text>
<view class="page-actions">
<button @click="handleAdd" class="btn btn-primary">{{ addButtonText }}</button>
<button @click="handleExport" class="btn btn-default">导出</button>
</view>
</view>
<!-- 搜索表单 -->
<view class="search-form-container bg-white p-md rounded shadow-sm">
<SearchForm :fields="searchFields" @search="handleSearch" />
</view>
<!-- 列表内容 -->
<view class="list-container bg-white p-md rounded shadow-sm">
<view class="list-toolbar flex-between mb-md">
<text class="text-secondary">共 {{ total }} 条记录</text>
<view class="list-tools">
<button @click="handleRefresh" class="btn btn-sm">刷新</button>
<button @click="handleDelete" class="btn btn-sm">删除</button>
</view>
</view>
<view class="list-table">
<table-view :data="listData" :columns="columns" @row-click="handleRowClick" />
</view>
</view>
<!-- 分页 -->
<view class="pagination-container flex-center mt-lg">
<pagination
:current="pagination.current"
:pageSize="pagination.pageSize"
:total="total"
@change="handlePageChange"
/>
</view>
</view>
</AdminLayout>
</template>
<script setup lang="uts">
import { ref, reactive } from 'vue'
import AdminLayout from '@/layouts/admin/AdminLayout.uvue'
import SearchForm from '@/layouts/admin/components/SearchForm.uvue'
import TableView from '@/components/TableView.uvue'
import Pagination from '@/components/Pagination.uvue'
// 页面配置
const currentPage = 'list-page'
const pageTitle = '数据列表'
const addButtonText = '新增'
// 数据状态
const listData = ref([])
const total = ref(0)
// 分页信息
const pagination = reactive({
current: 1,
pageSize: 20,
})
// 搜索字段配置
const searchFields = ref([
{ key: 'name', label: '名称', type: 'text', placeholder: '请输入名称' },
{ key: 'status', label: '状态', type: 'select', options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 },
]},
{ key: 'date', label: '日期', type: 'daterange' },
])
// 表格列配置
const columns = ref([
{ prop: 'id', label: 'ID', width: 60 },
{ prop: 'name', label: '名称', minWidth: 120 },
{ prop: 'status', label: '状态', width: 80, formatter: (row: any) => row.status ? '启用' : '禁用' },
{ prop: 'createTime', label: '创建时间', width: 160 },
{ label: '操作', width: 120, fixed: 'right', slots: ['actions'] },
])
// 方法
const handleSearch = (filters: any) => {
pagination.current = 1
fetchList(filters)
}
const handlePageChange = (page: number) => {
pagination.current = page
fetchList()
}
const handleAdd = () => {
uni.navigateTo({ url: '/pages/mall/admin/list/add' })
}
const handleRefresh = () => {
fetchList()
}
const handleDelete = () => {
// 删除逻辑
}
const handleRowClick = (row: any) => {
uni.navigateTo({ url: `/pages/mall/admin/list/edit?id=${row.id}` })
}
const handleExport = () => {
// 导出逻辑
}
const fetchList = async (filters?: any) => {
// API 请求逻辑
// listData.value = response.data
// total.value = response.total
}
</script>
<style scoped lang="scss">
.list-page {
padding: 20px;
}
.page-header {
margin-bottom: 20px;
}
.page-title {
font-size: $font-size-lg;
font-weight: 600;
color: $text-primary;
}
.page-actions {
display: flex;
gap: 10px;
}
.search-form-container {
margin-bottom: 20px;
}
.list-container {
margin-bottom: 20px;
}
.list-toolbar {
border-bottom: 1px solid $border-color;
padding-bottom: 12px;
}
.list-tools {
display: flex;
gap: 10px;
}
.pagination-container {
margin: 20px 0;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: $radius;
font-size: $font-size;
cursor: pointer;
transition: all $transition-duration $transition-timing;
}
.btn-primary {
background-color: $primary-color;
color: #fff;
}
.btn-primary:active {
opacity: 0.8;
}
.btn-default {
background-color: $background-color;
color: $text-primary;
border: 1px solid $border-color;
}
.btn-sm {
padding: 6px 12px;
font-size: $font-size-sm;
}
</style>
```
#### 3.2 表单页面
**pages/mall/admin/template/FormPage.uvue**
```uvue
<template>
<AdminLayout :currentPage="currentPage">
<view class="form-page">
<!-- 页面标题 -->
<view class="page-header">
<text class="page-title">{{ pageTitle }}</text>
</view>
<!-- 表单容器 -->
<form-view
ref="formRef"
:model="formData"
:fields="formFields"
:loading="loading"
@submit="handleSubmit"
/>
</view>
</AdminLayout>
</template>
<script setup lang="uts">
import { ref, reactive } from 'vue'
import AdminLayout from '@/layouts/admin/AdminLayout.uvue'
import FormView from '@/components/FormView.uvue'
const currentPage = 'form-page'
const pageTitle = '编辑数据'
const loading = ref(false)
const formData = reactive({
name: '',
description: '',
status: 1,
category: '',
tags: [],
attachments: [],
})
const formFields = ref([
{
key: 'name',
label: '名称',
type: 'text',
required: true,
placeholder: '请输入名称',
rules: [{ required: true, message: '名称不能为空' }],
},
{
key: 'description',
label: '描述',
type: 'textarea',
placeholder: '请输入描述',
rows: 4,
},
{
key: 'category',
label: '分类',
type: 'select',
required: true,
options: [
{ label: '分类1', value: 1 },
{ label: '分类2', value: 2 },
],
},
{
key: 'status',
label: '状态',
type: 'radio',
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 },
],
},
{
key: 'tags',
label: '标签',
type: 'checkbox',
options: [
{ label: '热销', value: 'hot' },
{ label: '新品', value: 'new' },
{ label: '推荐', value: 'recommend' },
],
},
{
key: 'attachments',
label: '附件',
type: 'upload',
multiple: true,
accept: 'file',
},
])
const handleSubmit = async (data: any) => {
loading.value = true
try {
// API 提交逻辑
uni.showToast({ title: '提交成功', icon: 'success' })
setTimeout(() => {
uni.navigateBack()
}, 1500)
} catch (error) {
uni.showToast({ title: '提交失败', icon: 'error' })
} finally {
loading.value = false
}
}
</script>
<style scoped lang="scss">
.form-page {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.page-header {
margin-bottom: 24px;
}
.page-title {
font-size: $font-size-lg;
font-weight: 600;
color: $text-primary;
}
</style>
```
---
## 组件库清单
### 必须实现的组件
#### 1. 基础组件
- [ ] Button按钮
- [ ] Input输入框
- [ ] Select选择器
- [ ] Checkbox复选框
- [ ] Radio单选框
- [ ] Switch开关
- [ ] DatePicker日期选择器
#### 2. 容器组件
- [ ] Card卡片
- [ ] Modal模态框
- [ ] Drawer抽屉
- [ ] Tabs标签页
- [ ] Collapse折叠面板
#### 3. 数据展示
- [ ] Table表格
- [ ] List列表
- [ ] Pagination分页
- [ ] Tree树形控件
- [ ] Empty空状态
#### 4. 表单组件
- [ ] Form表单
- [ ] Upload上传
- [ ] SearchForm搜索表单
- [ ] Filter高级筛选
#### 5. 反馈组件
- [ ] Message消息
- [ ] Toast提示
- [ ] Confirm确认框
- [ ] Loading加载中
#### 6. 导航组件
- [ ] Menu菜单
- [ ] Breadcrumb面包屑
- [ ] Tabs标签
- [ ] Pagination分页
---
## 迁移检查清单
### Phase 1: 基础设施
- [ ] 创建样式系统文件
- [ ] uni.scss全局变量
- [ ] styles/common.scss通用类
- [ ] styles/animate.scss动画
- [ ] 更新 AdminLayout 支持多布局
- [ ] Defaults 布局
- [ ] Classic 布局
- [ ] Columns 布局
- [ ] 配置工程化工具
- [ ] .eslintrc 配置
- [ ] .prettierrc 配置
- [ ] tsconfig.json 优化
### Phase 2: 核心组件
- [ ] 实现基础 UI 组件库
- [ ] 实现 FormView 表单组件
- [ ] 实现 TableView 表格组件
- [ ] 实现 SearchForm 搜索组件
### Phase 3: 页面模板
- [ ] 创建列表页面模板
- [ ] 创建表单页面模板
- [ ] 创建详情页面模板
- [ ] 创建仪表板页面模板
### Phase 4: 样式规范化
- [ ] 统一所有页面的样式
- [ ] 规范间距使用
- [ ] 规范颜色使用
- [ ] 规范排版样式
### Phase 5: 文档完善
- [ ] 编写组件使用文档
- [ ] 编写样式规范文档
- [ ] 编写页面开发指南
- [ ] 维护变更日志
---
## 推荐阅读
- [ADMIN_SIDEBAR_COMPLETE_GUIDE.md](ADMIN_SIDEBAR_COMPLETE_GUIDE.md) - 侧边栏完整指南
- [CRMEB_DASHBOARD_GUIDE.md](CRMEB_DASHBOARD_GUIDE.md) - 仪表板设计指南
- [UNI_APP_X_PAGE_FIX_GUIDE.md](UNI_APP_X_PAGE_FIX_GUIDE.md) - uni-app-x 页面修复指南
---
**文档维护者**: AI Assistant
**最后更新**: 2026-01-31
**版本**: 1.0