324 lines
7.9 KiB
Markdown
324 lines
7.9 KiB
Markdown
# 项目开发指南(Vue 3 + Vite + Element Plus + Axios)
|
||
|
||
> 本文档面向日常开发与维护,覆盖环境准备、目录结构、编码规范、网络请求、UI 使用、构建部署与常见问题等。
|
||
|
||
## 一、项目概览
|
||
|
||
- 框架:Vue 3(Composition API)
|
||
- 构建:Vite 5
|
||
- 组件库:Element Plus
|
||
- 网络:Axios(已内置实例与拦截器)
|
||
- 运行脚本:`npm run dev | build | preview`
|
||
|
||
## 二、环境要求
|
||
|
||
- Node.js:建议 18+(可用 `node -v` 检查)
|
||
- 包管理器:npm(内置于 Node)或 pnpm/yarn(任选其一)
|
||
- 操作系统:Windows / macOS / Linux
|
||
|
||
## 三、目录结构
|
||
|
||
当前主要目录:
|
||
|
||
```
|
||
├─ index.html # 应用入口 HTML
|
||
├─ vite.config.js # Vite 配置
|
||
├─ package.json # 脚本与依赖
|
||
├─ src/
|
||
│ ├─ main.js # 应用入口,注册 Element Plus
|
||
│ ├─ App.vue # 示例页面(按钮 + 请求演示)
|
||
│ └─ plugins/
|
||
│ └─ http.js # Axios 实例与拦截器
|
||
└─ docs/
|
||
└─ 开发指南.md # 本文档
|
||
```
|
||
|
||
推荐扩展(按需新增):
|
||
|
||
```
|
||
src/
|
||
├─ api/ # 接口定义与请求函数(封装到 http 实例上)
|
||
├─ assets/ # 静态资源(图片、字体等)
|
||
├─ components/ # 通用基础组件
|
||
├─ views/ # 页面级组件
|
||
├─ router/ # 路由(如使用 Vue Router)
|
||
├─ store/ # 状态管理(如使用 Pinia)
|
||
├─ styles/ # 全局样式、变量、主题定制
|
||
└─ utils/ # 工具方法(格式化、校验、下载等)
|
||
```
|
||
|
||
## 四、快速开始
|
||
|
||
- 安装依赖:`npm install`
|
||
- 启动开发:`npm run dev`(默认 http://localhost:5173)
|
||
- 构建产物:`npm run build`(输出至 `dist/`)
|
||
- 本地预览:`npm run preview`
|
||
|
||
## 五、配置说明
|
||
|
||
### 1. 环境变量
|
||
|
||
建议使用 Vite 的环境文件管理不同环境:
|
||
|
||
- `.env.development`(开发)
|
||
- `.env.production`(生产)
|
||
|
||
示例内容:
|
||
|
||
```
|
||
# .env.development
|
||
VITE_API_BASE=https://dev-api.example.com
|
||
|
||
# .env.production
|
||
VITE_API_BASE=https://api.example.com
|
||
```
|
||
|
||
在代码中使用:
|
||
|
||
```js
|
||
const baseURL = import.meta.env.VITE_API_BASE
|
||
```
|
||
|
||
### 2. Vite 配置(`vite.config.js`)
|
||
|
||
常用配置要点:
|
||
- 别名:为 `src` 设置 `@` 方便导入。
|
||
- 代理:开发阶段转发 API,避免 CORS。
|
||
|
||
示例(按需修改后替换到 `vite.config.js`):
|
||
|
||
```js
|
||
import { defineConfig } from 'vite'
|
||
import vue from '@vitejs/plugin-vue'
|
||
import path from 'node:path'
|
||
|
||
export default defineConfig({
|
||
plugins: [vue()],
|
||
resolve: {
|
||
alias: { '@': path.resolve(__dirname, 'src') },
|
||
},
|
||
server: {
|
||
proxy: {
|
||
'/api': {
|
||
target: 'https://dev-api.example.com',
|
||
changeOrigin: true,
|
||
rewrite: (p) => p.replace(/^\/api/, ''),
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
### 3. Axios 配置(`src/plugins/http.js`)
|
||
|
||
当前实现:
|
||
- `baseURL: '/'`(建议改为 `import.meta.env.VITE_API_BASE`)
|
||
- 超时 15s
|
||
- 预留请求拦截器(注入 Token)与响应拦截器(统一错误处理)
|
||
|
||
建议修改:
|
||
|
||
```js
|
||
const http = axios.create({
|
||
baseURL: import.meta.env.VITE_API_BASE || '/',
|
||
timeout: 15000,
|
||
})
|
||
```
|
||
|
||
统一错误处理示例(可在响应拦截器中加入):
|
||
|
||
```js
|
||
import { ElMessage } from 'element-plus'
|
||
|
||
http.interceptors.response.use(
|
||
(res) => res,
|
||
(error) => {
|
||
const msg = error?.response?.data?.message || error.message || '请求失败'
|
||
ElMessage.error(msg)
|
||
return Promise.reject(error)
|
||
}
|
||
)
|
||
```
|
||
|
||
## 六、代码与组件规范
|
||
|
||
- 组件目录:一个组件一个目录(可含 `index.vue` / `index.ts`)。
|
||
- 命名规范:
|
||
- 组件名:`PascalCase`(如 `UserCard.vue`)。
|
||
- 变量/函数:`camelCase`。
|
||
- 文件:`kebab-case`(工具类/样式)。
|
||
- 组件结构:`<template>` / `<script setup>` / `<style scoped>` 顺序。
|
||
- 导入顺序:Vue/第三方 → 别名 `@` → 相对路径。
|
||
- 提交信息:语义化(feat/fix/docs/chore/refactor/style/test/build)。
|
||
|
||
## 七、UI 与交互(Element Plus)
|
||
|
||
- 全量引入已配置于 `src/main.js`:
|
||
|
||
```js
|
||
import ElementPlus from 'element-plus'
|
||
import 'element-plus/dist/index.css'
|
||
app.use(ElementPlus)
|
||
```
|
||
|
||
- 主题定制:
|
||
- 推荐在 `src/styles/variables.scss` 定义主题变量,按需覆盖 Element Plus 变量。
|
||
- 也可使用暗色主题与自定义主题(参考官方文档)。
|
||
|
||
- 常用交互:
|
||
- 消息:`ElMessage.success('保存成功')`
|
||
- 弹窗:`ElMessageBox.confirm('确定操作吗?', '提示')`
|
||
- 加载:`ElLoading.service({ text: '加载中...' })`
|
||
|
||
## 八、网络请求规范
|
||
|
||
- 统一通过 `src/plugins/http.js` 导出的 `http` 发起请求:
|
||
|
||
```js
|
||
import http from '@/plugins/http'
|
||
|
||
export function fetchUser(id) {
|
||
return http.get(`/users/${id}`)
|
||
}
|
||
|
||
export function createUser(payload) {
|
||
return http.post('/users', payload)
|
||
}
|
||
```
|
||
|
||
- 结果解构与错误处理:
|
||
|
||
```js
|
||
try {
|
||
const { data } = await fetchUser(1)
|
||
// 根据后端约定判断 code / success
|
||
} catch (e) {
|
||
// 统一拦截器会提示,这里可按需记录或兜底
|
||
}
|
||
```
|
||
|
||
- 可选:取消请求(例如在切换路由或重复点击时):
|
||
|
||
```js
|
||
const controller = new AbortController()
|
||
http.get('/path', { signal: controller.signal })
|
||
// 需要时取消
|
||
controller.abort()
|
||
```
|
||
|
||
## 九、常见开发食谱
|
||
|
||
- 新增页面:
|
||
- 在 `src/views/` 新建页面组件,如 `UserList.vue`。
|
||
- 如使用路由,在 `router` 中注册路由并在入口挂载。
|
||
|
||
- 调用接口 + 加载态示例(参考 `App.vue`):
|
||
|
||
```vue
|
||
<script setup>
|
||
import { ref } from 'vue'
|
||
import http from '@/plugins/http'
|
||
|
||
const loading = ref(false)
|
||
const data = ref(null)
|
||
|
||
async function load() {
|
||
loading.value = true
|
||
try {
|
||
const res = await http.get('/example')
|
||
data.value = res.data
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
|
||
- 表单校验(Element Plus):
|
||
- 使用 `el-form` + `rules` + `el-form-item`,提交前 `formRef.validate()`。
|
||
|
||
- 消息提示:
|
||
- 成功:`ElMessage.success('操作成功')`
|
||
- 失败:`ElMessage.error('操作失败')`
|
||
|
||
## 十、路由与状态(可选集成)
|
||
|
||
- 安装:
|
||
- Vue Router:`npm i vue-router`
|
||
- Pinia:`npm i pinia`
|
||
|
||
- 快速示例(Router):
|
||
|
||
```js
|
||
// src/router/index.js
|
||
import { createRouter, createWebHistory } from 'vue-router'
|
||
|
||
const routes = [
|
||
{ path: '/', component: () => import('@/views/Home.vue') },
|
||
]
|
||
|
||
export default createRouter({ history: createWebHistory(), routes })
|
||
```
|
||
|
||
```js
|
||
// main.js
|
||
import router from '@/router'
|
||
app.use(router)
|
||
```
|
||
|
||
- 快速示例(Pinia):
|
||
|
||
```js
|
||
// src/store/index.js
|
||
import { createPinia, defineStore } from 'pinia'
|
||
export const pinia = createPinia()
|
||
export const useCounter = defineStore('counter', {
|
||
state: () => ({ count: 0 }),
|
||
})
|
||
```
|
||
|
||
```js
|
||
// main.js
|
||
import { pinia } from '@/store'
|
||
app.use(pinia)
|
||
```
|
||
|
||
## 十一、构建与部署
|
||
|
||
- 构建命令:`npm run build`,产物在 `dist/`
|
||
- 预览构建:`npm run preview`
|
||
- 静态资源路径:如需部署到子路径,设置 `base`(`vite.config.js`)或 `--base`。
|
||
- Nginx 示例:
|
||
|
||
```
|
||
location / {
|
||
try_files $uri $uri/ /index.html;
|
||
}
|
||
|
||
location /api/ {
|
||
proxy_pass https://api.example.com/;
|
||
}
|
||
```
|
||
|
||
## 十二、质量保障(可选)
|
||
|
||
- 代码格式化:建议接入 Prettier + ESLint。
|
||
- 提交规范:建议使用 Commitlint + Husky 规范提交信息。
|
||
- 单元测试:可引入 Vitest 进行组件与函数测试。
|
||
|
||
## 十三、常见问题(FAQ)
|
||
|
||
- 无法请求跨域?
|
||
- 开发环境配置 Vite 代理(见上文 server.proxy)。
|
||
- 生产环境由网关或 Nginx 统一转发。
|
||
|
||
- 接口报错但页面无提示?
|
||
- 确认是否已在响应拦截器中调用 `ElMessage.error`。
|
||
|
||
- Element Plus 主题不生效?
|
||
- 确保样式覆盖顺序正确,且未被 `scoped` 限制。
|
||
|
||
---
|
||
|
||
如需我帮你接入 Router/Pinia、主题定制或代码规范工具链,请告诉我具体偏好与要求。
|