项目初始化与 UI 架构
约 564 字大约 2 分钟
布欧-Lewyon
2026-05-15
首页 › Vue › 实战项目 › 项目初始化与 UI 架构
本节开始搭建一个企业级全栈看板管理应用,覆盖路由权限、状态管理、API 集成、测试与部署。
技术栈
| 层级 | 技术 |
|---|---|
| 框架 | Vue 3 + Vite |
| 语言 | TypeScript |
| 路由 | Vue Router 4 |
| 状态管理 | Pinia |
| HTTP | Axios |
| UI | 手写组件 + CSS Variables |
| 拖拽 | vuedraggable@next / dnd-kit 适配 |
| 测试 | Vitest + Vue Test Utils + Playwright |
| 部署 | Docker + CI/CD |
项目初始化
npm create vue@latest kanban-app -- --typescript --router --pinia
cd kanban-app
npm install axios vuedraggable@next
npm install -D vitest @vue/test-utils @playwright/test目录结构
src/
├── main.ts
├── App.vue
├── api/
│ ├── request.ts # Axios 实例
│ ├── board.ts # 看板 API
│ └── auth.ts # 认证 API
├── assets/
│ └── styles/
│ ├── variables.css # CSS 变量
│ └── global.css # 全局样式
├── components/
│ ├── kanban/
│ │ ├── KanbanBoard.vue
│ │ ├── KanbanColumn.vue
│ │ └── KanbanCard.vue
│ └── common/
│ ├── AppHeader.vue
│ ├── AppSidebar.vue
│ └── Permission.vue
├── composables/
│ ├── useBoard.ts
│ ├── useAuth.ts
│ └── usePermission.ts
├── router/
│ └── index.ts
├── stores/
│ ├── board.ts
│ ├── auth.ts
│ └── app.ts
├── types/
│ ├── board.ts
│ └── user.ts
└── views/
├── Login.vue
├── Dashboard.vue
├── BoardDetail.vue
└── admin/
└── UserManage.vue基础类型
// types/board.ts
export interface Board {
id: number
title: string
columns: Column[]
createdAt: string
}
export interface Column {
id: number
title: string
tasks: Task[]
}
export interface Task {
id: number
title: string
description?: string
assignee?: string
priority: 'low' | 'medium' | 'high'
tags: string[]
dueDate?: string
}// types/user.ts
export interface User {
id: number
username: string
role: 'admin' | 'editor' | 'viewer'
avatar?: string
}
export interface AuthState {
user: User | null
token: string | null
permissions: string[]
}Axios 封装
// api/request.ts
import axios from 'axios'
import { useAuthStore } from '@/stores/auth'
import router from '@/router'
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE || '/api',
timeout: 10000
})
// 请求拦截:带 Token
request.interceptors.request.use((config) => {
const auth = useAuthStore()
if (auth.token) {
config.headers.Authorization = `Bearer ${auth.token}`
}
return config
})
// 响应拦截:统一错误处理
request.interceptors.response.use(
(res) => res.data,
(error) => {
if (error.response?.status === 401) {
useAuthStore().logout()
router.push('/login')
}
return Promise.reject(error)
}
)
export default request全局样式
/* assets/styles/variables.css */
:root {
--color-primary: #1890ff;
--color-success: #52c41a;
--color-warning: #faad14;
--color-danger: #ff4d4f;
--color-bg: #f5f5f5;
--color-card: #ffffff;
--color-text: #333333;
--color-text-secondary: #666666;
--sidebar-width: 240px;
--header-height: 56px;
--border-radius: 8px;
/* 暗色主题 */
--color-bg-dark: #141414;
--color-card-dark: #1f1f1f;
--color-text-dark: #e0e0e0;
}Layout 架构
<!-- App.vue -->
<script setup lang="ts">
import AppHeader from '@/components/common/AppHeader.vue'
import AppSidebar from '@/components/common/AppSidebar.vue'
import { useAppStore } from '@/stores/app'
const appStore = useAppStore()
</script>
<template>
<div class="app-layout" :class="{ 'theme-dark': appStore.theme === 'dark' }">
<AppHeader />
<div class="app-body">
<AppSidebar v-if="appStore.isLoggedIn" />
<main class="app-main">
<router-view />
</main>
</div>
</div>
</template>小结
本节搭建了项目的工程骨架:
| 模块 | 内容 |
|---|---|
| Vite 脚手架 | Vue 3 + TS + Router + Pinia |
| 目录结构 | 按功能分层(api / components / stores / views) |
| Axios 封装 | 拦截器 + Token + 401 处理 |
| CSS Variables | 主题系统(亮/暗色) |
| Layout | Header + Sidebar + Content |
下一节:状态管理与 API 集成
