create-vite-vue 1.2.6 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +16 -2
- package/package.json +1 -1
- package/template/axios-js/.env +1 -0
- package/template/axios-js/src/utils/request.js +1 -1
- package/template/axios-ts/.env +1 -0
- package/template/axios-ts/src/utils/request.ts +5 -5
- package/template/axios-ts/src/utils/requestCache.ts +9 -7
- package/template/base-js/README.md +238 -14
- package/template/base-ts/README.md +238 -14
- package/template/tailwind-js/postcss.config.mjs +5 -0
- package/template/tailwind-ts/postcss.config.mjs +5 -0
- package/template/base-ts/types/request.d.ts +0 -148
- /package/template/base-js/{types → src/types}/request.d.ts +0 -0
package/bin/index.js
CHANGED
|
@@ -89,7 +89,8 @@ const __dirname = path.dirname(__filename)
|
|
|
89
89
|
const pluginOptions = [
|
|
90
90
|
{ title: 'VueUse(实用 Composition API)', value: 'vueuse' },
|
|
91
91
|
{ title: 'Lodash(实用工具库)', value: 'lodash' },
|
|
92
|
-
{ title: 'Day.js(轻量日期处理)', value: 'dayjs' }
|
|
92
|
+
{ title: 'Day.js(轻量日期处理)', value: 'dayjs' },
|
|
93
|
+
{ title: 'Tailwind CSS(原子化 CSS)', value: 'tailwind' }
|
|
93
94
|
]
|
|
94
95
|
|
|
95
96
|
const { selectedPlugins } = await prompts({
|
|
@@ -131,6 +132,15 @@ const __dirname = path.dirname(__filename)
|
|
|
131
132
|
indexContent.replace(/<title>.*<\/title>/, `<title>${projectName}</title>`)
|
|
132
133
|
)
|
|
133
134
|
}
|
|
135
|
+
// 追加 Tailwind CSS 导入
|
|
136
|
+
if (extraPlugins.includes('tailwind')) {
|
|
137
|
+
const stylePath = path.join(targetDir, 'src/style.css')
|
|
138
|
+
const original = fs.readFileSync(stylePath, 'utf-8')
|
|
139
|
+
// 在第一行追加,不重复添加
|
|
140
|
+
if (!original.startsWith('@import "tailwindcss";')) {
|
|
141
|
+
fs.writeFileSync(stylePath, `@import "tailwindcss";\n${original}`)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
134
144
|
|
|
135
145
|
// 5️⃣ 拷贝可选模板(基础功能)
|
|
136
146
|
const copy = name => {
|
|
@@ -142,7 +152,7 @@ const __dirname = path.dirname(__filename)
|
|
|
142
152
|
|
|
143
153
|
// ========== 新增:拷贝增强插件模板 ==========
|
|
144
154
|
for (const plugin of extraPlugins) {
|
|
145
|
-
const templateName =
|
|
155
|
+
const templateName = `${plugin}-${language === 'ts' ? 'ts' : 'js'}`
|
|
146
156
|
const templatePath = path.resolve(__dirname, `../template/${templateName}`)
|
|
147
157
|
if (fs.existsSync(templatePath)) {
|
|
148
158
|
fs.cpSync(templatePath, targetDir, { recursive: true })
|
|
@@ -242,6 +252,7 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
242
252
|
if (extraPlugins.includes('vueuse')) optionalDeps['@vueuse/core'] = '^14.1.0'
|
|
243
253
|
if (extraPlugins.includes('dayjs')) optionalDeps['dayjs'] = '^1.11.19'
|
|
244
254
|
if (extraPlugins.includes('lodash')) optionalDeps['lodash'] = '^4.17.23'
|
|
255
|
+
|
|
245
256
|
// ========== 增强插件依赖结束 ==========
|
|
246
257
|
|
|
247
258
|
let depsStr = ''
|
|
@@ -261,6 +272,9 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
261
272
|
// 8️⃣ 安装依赖
|
|
262
273
|
console.log('📦 安装依赖中...')
|
|
263
274
|
execSync('npm install', { cwd: targetDir, stdio: 'inherit' })
|
|
275
|
+
if (extraPlugins.includes('tailwind')) {
|
|
276
|
+
execSync('npm install tailwindcss @tailwindcss/postcss postcss', { cwd: targetDir, stdio: 'inherit' })
|
|
277
|
+
}
|
|
264
278
|
|
|
265
279
|
// 9️⃣ 运行 dev
|
|
266
280
|
if (runDev) {
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_API_BASE_URL=http://localhost:8080/api
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_API_BASE_URL=http://localhost:8080/api
|
|
@@ -2,7 +2,7 @@ import axios from 'axios'
|
|
|
2
2
|
import { addPendingRequest, removePendingRequest } from './requestCache'
|
|
3
3
|
|
|
4
4
|
const service = axios.create({
|
|
5
|
-
baseURL: '/api',
|
|
5
|
+
baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
|
|
6
6
|
timeout: 10000
|
|
7
7
|
})
|
|
8
8
|
|
|
@@ -12,9 +12,9 @@ service.interceptors.request.use(
|
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
14
|
addPendingRequest(config)
|
|
15
|
-
} catch
|
|
15
|
+
} catch(error) {
|
|
16
16
|
// 如果是取消请求,直接reject
|
|
17
|
-
if
|
|
17
|
+
if(error.isCancel) {
|
|
18
18
|
return Promise.reject({ canceled: true, message: '请求取消' })
|
|
19
19
|
}
|
|
20
20
|
throw error
|
|
@@ -34,11 +34,11 @@ service.interceptors.response.use(
|
|
|
34
34
|
},
|
|
35
35
|
error => {
|
|
36
36
|
// 即使是错误(包括网络错误)也要清理
|
|
37
|
-
if
|
|
37
|
+
if(error.config) {
|
|
38
38
|
removePendingRequest(error.config)
|
|
39
39
|
}
|
|
40
40
|
// 判断是否是重复请求被取消
|
|
41
|
-
if
|
|
41
|
+
if(error.canceled) {
|
|
42
42
|
return Promise.reject(error)
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
+
import { InternalAxiosRequestConfig } from "axios"
|
|
2
|
+
|
|
1
3
|
const pendingRequests = new Map()
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* 生成请求唯一kaey
|
|
5
|
-
* @param {
|
|
7
|
+
* @param {InternalAxiosRequestConfig} config 请求配置对象
|
|
6
8
|
* 注意:只适用于可序列化的 params 和 data(如普通对象)
|
|
7
9
|
*/
|
|
8
|
-
function generateReqKey (config) {
|
|
10
|
+
function generateReqKey (config: InternalAxiosRequestConfig) {
|
|
9
11
|
const { method, url, params, data } = config
|
|
10
12
|
return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* 添加pending请求,并自动取消请求
|
|
15
|
-
* @param {
|
|
17
|
+
* @param {InternalAxiosRequestConfig} config 请求配置对象
|
|
16
18
|
*/
|
|
17
|
-
export function addPendingRequest (config) {
|
|
19
|
+
export function addPendingRequest (config: InternalAxiosRequestConfig) {
|
|
18
20
|
// 获取请求key
|
|
19
21
|
const requestKey = generateReqKey(config)
|
|
20
22
|
// 如果存在相同请求,取消当前请求
|
|
21
|
-
if
|
|
23
|
+
if(pendingRequests.has(requestKey)) {
|
|
22
24
|
const error = new Error('重复请求') as Error & { isCancel: boolean }
|
|
23
25
|
error.isCancel = true
|
|
24
26
|
throw error
|
|
@@ -33,9 +35,9 @@ export function addPendingRequest (config) {
|
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
* 移除已完成/失败/取消的请求
|
|
36
|
-
* @param {
|
|
38
|
+
* @param {InternalAxiosRequestConfig} config 请求配置对象
|
|
37
39
|
*/
|
|
38
|
-
export function removePendingRequest (config) {
|
|
40
|
+
export function removePendingRequest (config: InternalAxiosRequestConfig) {
|
|
39
41
|
const requestKey = generateReqKey(config)
|
|
40
42
|
pendingRequests.delete(requestKey)
|
|
41
43
|
}
|
|
@@ -1,32 +1,256 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ⚡ create-vite-vue
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
🚀 一个开箱即用的 Vue 3 项目快速生成工具
|
|
4
|
+
基于 Vite 构建,支持按需组合常用技术栈,直接生成可落地的项目结构。
|
|
4
5
|
|
|
6
|
+
---
|
|
5
7
|
|
|
8
|
+
## ✨ 特性一览
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
- ⚡ 基于 Vite + Vue 3,启动快、构建快
|
|
11
|
+
- 📜 支持 JavaScript / TypeScript 自由选择
|
|
12
|
+
- 🧭 可选集成 Vue Router
|
|
13
|
+
- 🗂️ 可选集成 Pinia(含持久化)
|
|
14
|
+
- 📡 内置 Axios 请求方案
|
|
15
|
+
- 🖥️ / 📱 支持 Element Plus / Vant
|
|
16
|
+
- 🧰 常用工具库可选:VueUse / Lodash / Day.js
|
|
17
|
+
- 🧩 结构清晰,适合直接写业务
|
|
18
|
+
- 🔧 内置 Vite 配置优化构建输出和资源路径
|
|
19
|
+
- 🌐 本地及网络访问启动日志显示
|
|
20
|
+
- 📝 自定义 Banner 插件显示项目信息
|
|
21
|
+
- 🎨 可选集成 Tailwind CSS(通过 postcss 配置)
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🧩 技术栈
|
|
26
|
+
|
|
27
|
+
⚡ Vite
|
|
28
|
+
🟢 Vue 3
|
|
29
|
+
📜 JavaScript / 🔷 TypeScript
|
|
30
|
+
🧭 Vue Router
|
|
31
|
+
🗂️ Pinia
|
|
32
|
+
📡 Axios
|
|
33
|
+
🖥️ Element Plus / 📱 Vant
|
|
34
|
+
🧰 VueUse · Lodash · Day.js
|
|
35
|
+
🎨 Tailwind CSS
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 📦 生成后的项目包含什么?
|
|
40
|
+
|
|
41
|
+
根据你的选择,工具会自动生成一个标准化 Vue 3 项目结构,主要包括:
|
|
42
|
+
|
|
43
|
+
### 基础内容(必选)
|
|
44
|
+
|
|
45
|
+
- 项目入口页面
|
|
46
|
+
- src 源码目录
|
|
47
|
+
- 项目启动入口文件
|
|
48
|
+
- 根组件与默认欢迎页
|
|
49
|
+
- 全局样式文件
|
|
50
|
+
- Vite 配置文件
|
|
51
|
+
- 依赖管理文件(已自动注入所选功能)
|
|
52
|
+
- 路径别名配置(@ 指向 src)
|
|
53
|
+
- postcss.config.mjs(Tailwind CSS 配置,可选)
|
|
54
|
+
|
|
55
|
+
这些内容已经帮你处理好基础配置,可直接开始开发,无需清理模板代码。
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 📁 项目目录结构说明
|
|
60
|
+
|
|
61
|
+
project-name
|
|
62
|
+
├─ public/ —— 公共静态资源目录
|
|
63
|
+
│ └─ favicon.ico
|
|
64
|
+
├─ src/
|
|
65
|
+
│ ├─ api/ —— 接口请求封装目录
|
|
66
|
+
│ ├─ assets/ —— 图片、字体等静态资源
|
|
67
|
+
│ ├─ components/ —— 公共组件目录
|
|
68
|
+
│ ├─ router/ —— 路由配置(可选)
|
|
69
|
+
│ ├─ stores/ —— Pinia 状态管理(可选)
|
|
70
|
+
│ ├─ types/ —— 类型声明文件
|
|
71
|
+
│ ├─ utils/ —— 工具方法、请求封装
|
|
72
|
+
│ ├─ views/ —— 页面级组件(路由页面)
|
|
73
|
+
│ ├─ App.vue —— 根组件
|
|
74
|
+
│ ├─ main.js / main.ts —— 项目启动入口
|
|
75
|
+
│ └─ style.css —— 全局样式文件
|
|
76
|
+
├─ index.html —— 项目入口页面
|
|
77
|
+
├─ jsconfig.json / tsconfig.json —— 路径别名与编译配置
|
|
78
|
+
├─ package.json —— 项目依赖与脚本配置
|
|
79
|
+
├─ postcss.config.mjs —— Tailwind CSS 配置文件(可选)
|
|
80
|
+
├─ README.md —— 项目说明文档
|
|
81
|
+
└─ vite.config.ts —— Vite 开发与构建配置
|
|
82
|
+
|
|
83
|
+
### 目录说明(白话版)
|
|
84
|
+
|
|
85
|
+
- **public**:放不会被打包处理的静态资源
|
|
86
|
+
- **assets**:项目中使用的图片、字体等资源
|
|
87
|
+
- **components**:可复用的通用组件
|
|
88
|
+
- **views**:页面级组件,通常与路由一一对应
|
|
89
|
+
- **router**:统一管理页面路由规则
|
|
90
|
+
- **stores**:全局状态管理目录
|
|
91
|
+
- **utils**:请求封装、工具方法等公共逻辑
|
|
92
|
+
- **api**:接口请求封装目录
|
|
93
|
+
- **types**:TypeScript 类型定义
|
|
94
|
+
- **postcss.config.mjs**:Tailwind CSS 配置,可根据需求修改
|
|
95
|
+
- **README.md**:项目说明文档
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## ⚙️ 使用方式
|
|
100
|
+
|
|
101
|
+
1. 创建项目
|
|
102
|
+
```bash
|
|
103
|
+
npm create vite-vue@latest
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. 进入项目目录
|
|
107
|
+
```bash
|
|
108
|
+
cd 项目名
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
3. 安装依赖 (已自动执行可省略)
|
|
112
|
+
```bash
|
|
113
|
+
npm install
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
4. 启动开发环境
|
|
117
|
+
```bash
|
|
12
118
|
npm run dev
|
|
13
119
|
```
|
|
14
120
|
|
|
121
|
+
> 如果在创建时选择了「立即运行」,工具会自动执行启动命令。
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 🌐 技术栈官网链接
|
|
126
|
+
|
|
127
|
+
- [Vite](https://vitejs.dev/)
|
|
128
|
+
- [Vue 3](https://vuejs.org/)
|
|
129
|
+
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
130
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
131
|
+
- [Vue Router](https://router.vuejs.org/)
|
|
132
|
+
- [Pinia](https://pinia.vuejs.org/)
|
|
133
|
+
- [Axios](https://axios-http.com/)
|
|
134
|
+
- [Element Plus](https://element-plus.org/)
|
|
135
|
+
- [Vant](https://vant-contrib.gitee.io/vant/)
|
|
136
|
+
- [VueUse](https://vueuse.org/)
|
|
137
|
+
- [Lodash](https://lodash.com/)
|
|
138
|
+
- [Day.js](https://day.js.org/)
|
|
139
|
+
- [Tailwind CSS](https://tailwindcss.com/)
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 🔧 常见需要调整的地方(具体文件示例)
|
|
144
|
+
|
|
145
|
+
### 1️⃣ 接口请求地址
|
|
146
|
+
|
|
147
|
+
文件:`src/utils/request.ts` `src/utils/request.js`
|
|
148
|
+
```ts
|
|
149
|
+
import axios from 'axios';
|
|
150
|
+
|
|
151
|
+
const service = axios.create({
|
|
152
|
+
baseURL: import.meta.env.VITE_API_BASE_URL || '/api', // 修改为你的接口地址
|
|
153
|
+
timeout: 10000,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// 示例请求
|
|
157
|
+
export const getUserList = () => request.get('/users');
|
|
158
|
+
|
|
159
|
+
export default service;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> 🔹 根据实际业务修改 `baseURL` 和各个接口方法。
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### 2️⃣ 本地代理配置
|
|
167
|
+
|
|
168
|
+
文件:`vite.config.ts` `vite.config.js`
|
|
169
|
+
```ts
|
|
170
|
+
import { defineConfig } from 'vite';
|
|
171
|
+
import vue from '@vitejs/plugin-vue';
|
|
172
|
+
|
|
173
|
+
export default defineConfig({
|
|
174
|
+
plugins: [vue()],
|
|
175
|
+
server: {
|
|
176
|
+
proxy: {
|
|
177
|
+
'/api': {
|
|
178
|
+
target: 'http://localhost:3000', // 修改为后端服务地址
|
|
179
|
+
changeOrigin: true,
|
|
180
|
+
rewrite: (path) => path.replace(/^\/api/, ''),
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
> 🔹 如果接口路径前有 `/api` 前缀,可通过代理去掉
|
|
188
|
+
> 🔹 根据本地后端环境调整 `target`
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### 3️⃣ 路由结构
|
|
193
|
+
|
|
194
|
+
文件:`src/router/index.ts` `src/router/index.js`
|
|
195
|
+
```ts
|
|
196
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
197
|
+
import Home from '../views/Home.vue';
|
|
15
198
|
|
|
199
|
+
const routes = [
|
|
200
|
+
{ path: '/', name: 'Home', component: Home },
|
|
201
|
+
{ path: '/about', name: 'About', component: () => import('../views/About.vue') },
|
|
202
|
+
];
|
|
16
203
|
|
|
17
|
-
|
|
204
|
+
const router = createRouter({
|
|
205
|
+
history: createWebHistory(),
|
|
206
|
+
routes,
|
|
207
|
+
});
|
|
18
208
|
|
|
19
|
-
|
|
20
|
-
utils/request.js
|
|
21
|
-
router/index.js
|
|
209
|
+
export default router;
|
|
22
210
|
```
|
|
23
211
|
|
|
212
|
+
> 🔹 根据实际业务新增或删除路由,并修改页面组件路径
|
|
24
213
|
|
|
214
|
+
---
|
|
25
215
|
|
|
26
|
-
|
|
216
|
+
### 4️⃣ 页面内容与样式
|
|
27
217
|
|
|
28
|
-
|
|
29
|
-
|
|
218
|
+
文件示例:`src/views/Home.vue`
|
|
219
|
+
```vue
|
|
220
|
+
<template>
|
|
221
|
+
<div class="home-container">
|
|
222
|
+
<h1>欢迎来到项目首页</h1>
|
|
223
|
+
<p>这里可以根据业务需求修改页面内容和样式</p>
|
|
224
|
+
</div>
|
|
225
|
+
</template>
|
|
226
|
+
|
|
227
|
+
<script setup lang="ts">
|
|
228
|
+
// 可引入接口数据
|
|
229
|
+
// import { getUserList } from '@/api'
|
|
230
|
+
</script>
|
|
231
|
+
|
|
232
|
+
<style scoped>
|
|
233
|
+
.home-container {
|
|
234
|
+
padding: 20px;
|
|
235
|
+
}
|
|
236
|
+
</style>
|
|
30
237
|
```
|
|
31
238
|
|
|
32
|
-
|
|
239
|
+
> 🔹 根据实际业务修改 HTML、样式、以及调用接口逻辑
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 🎯 适用场景
|
|
244
|
+
|
|
245
|
+
- Vue 3 新手快速上手
|
|
246
|
+
- 后台管理系统
|
|
247
|
+
- 中小型 Web 项目
|
|
248
|
+
- 练手项目 / 毕设 / 实战项目
|
|
249
|
+
- 不想每次重复配置环境的开发者
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 📄 License
|
|
254
|
+
|
|
255
|
+
MIT License
|
|
256
|
+
|
|
@@ -1,32 +1,256 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ⚡ create-vite-vue
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
🚀 一个开箱即用的 Vue 3 项目快速生成工具
|
|
4
|
+
基于 Vite 构建,支持按需组合常用技术栈,直接生成可落地的项目结构。
|
|
4
5
|
|
|
6
|
+
---
|
|
5
7
|
|
|
8
|
+
## ✨ 特性一览
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
- ⚡ 基于 Vite + Vue 3,启动快、构建快
|
|
11
|
+
- 📜 支持 JavaScript / TypeScript 自由选择
|
|
12
|
+
- 🧭 可选集成 Vue Router
|
|
13
|
+
- 🗂️ 可选集成 Pinia(含持久化)
|
|
14
|
+
- 📡 内置 Axios 请求方案
|
|
15
|
+
- 🖥️ / 📱 支持 Element Plus / Vant
|
|
16
|
+
- 🧰 常用工具库可选:VueUse / Lodash / Day.js
|
|
17
|
+
- 🧩 结构清晰,适合直接写业务
|
|
18
|
+
- 🔧 内置 Vite 配置优化构建输出和资源路径
|
|
19
|
+
- 🌐 本地及网络访问启动日志显示
|
|
20
|
+
- 📝 自定义 Banner 插件显示项目信息
|
|
21
|
+
- 🎨 可选集成 Tailwind CSS(通过 postcss 配置)
|
|
8
22
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🧩 技术栈
|
|
26
|
+
|
|
27
|
+
⚡ Vite
|
|
28
|
+
🟢 Vue 3
|
|
29
|
+
📜 JavaScript / 🔷 TypeScript
|
|
30
|
+
🧭 Vue Router
|
|
31
|
+
🗂️ Pinia
|
|
32
|
+
📡 Axios
|
|
33
|
+
🖥️ Element Plus / 📱 Vant
|
|
34
|
+
🧰 VueUse · Lodash · Day.js
|
|
35
|
+
🎨 Tailwind CSS
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 📦 生成后的项目包含什么?
|
|
40
|
+
|
|
41
|
+
根据你的选择,工具会自动生成一个标准化 Vue 3 项目结构,主要包括:
|
|
42
|
+
|
|
43
|
+
### 基础内容(必选)
|
|
44
|
+
|
|
45
|
+
- 项目入口页面
|
|
46
|
+
- src 源码目录
|
|
47
|
+
- 项目启动入口文件
|
|
48
|
+
- 根组件与默认欢迎页
|
|
49
|
+
- 全局样式文件
|
|
50
|
+
- Vite 配置文件
|
|
51
|
+
- 依赖管理文件(已自动注入所选功能)
|
|
52
|
+
- 路径别名配置(@ 指向 src)
|
|
53
|
+
- postcss.config.mjs(Tailwind CSS 配置,可选)
|
|
54
|
+
|
|
55
|
+
这些内容已经帮你处理好基础配置,可直接开始开发,无需清理模板代码。
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 📁 项目目录结构说明
|
|
60
|
+
|
|
61
|
+
project-name
|
|
62
|
+
├─ public/ —— 公共静态资源目录
|
|
63
|
+
│ └─ favicon.ico
|
|
64
|
+
├─ src/
|
|
65
|
+
│ ├─ api/ —— 接口请求封装目录
|
|
66
|
+
│ ├─ assets/ —— 图片、字体等静态资源
|
|
67
|
+
│ ├─ components/ —— 公共组件目录
|
|
68
|
+
│ ├─ router/ —— 路由配置(可选)
|
|
69
|
+
│ ├─ stores/ —— Pinia 状态管理(可选)
|
|
70
|
+
│ ├─ types/ —— 类型声明文件
|
|
71
|
+
│ ├─ utils/ —— 工具方法、请求封装
|
|
72
|
+
│ ├─ views/ —— 页面级组件(路由页面)
|
|
73
|
+
│ ├─ App.vue —— 根组件
|
|
74
|
+
│ ├─ main.js / main.ts —— 项目启动入口
|
|
75
|
+
│ └─ style.css —— 全局样式文件
|
|
76
|
+
├─ index.html —— 项目入口页面
|
|
77
|
+
├─ jsconfig.json / tsconfig.json —— 路径别名与编译配置
|
|
78
|
+
├─ package.json —— 项目依赖与脚本配置
|
|
79
|
+
├─ postcss.config.mjs —— Tailwind CSS 配置文件(可选)
|
|
80
|
+
├─ README.md —— 项目说明文档
|
|
81
|
+
└─ vite.config.ts —— Vite 开发与构建配置
|
|
82
|
+
|
|
83
|
+
### 目录说明(白话版)
|
|
84
|
+
|
|
85
|
+
- **public**:放不会被打包处理的静态资源
|
|
86
|
+
- **assets**:项目中使用的图片、字体等资源
|
|
87
|
+
- **components**:可复用的通用组件
|
|
88
|
+
- **views**:页面级组件,通常与路由一一对应
|
|
89
|
+
- **router**:统一管理页面路由规则
|
|
90
|
+
- **stores**:全局状态管理目录
|
|
91
|
+
- **utils**:请求封装、工具方法等公共逻辑
|
|
92
|
+
- **api**:接口请求封装目录
|
|
93
|
+
- **types**:TypeScript 类型定义
|
|
94
|
+
- **postcss.config.mjs**:Tailwind CSS 配置,可根据需求修改
|
|
95
|
+
- **README.md**:项目说明文档
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## ⚙️ 使用方式
|
|
100
|
+
|
|
101
|
+
1. 创建项目
|
|
102
|
+
```bash
|
|
103
|
+
npm create vite-vue@latest
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. 进入项目目录
|
|
107
|
+
```bash
|
|
108
|
+
cd 项目名
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
3. 安装依赖 (已自动执行可省略)
|
|
112
|
+
```bash
|
|
113
|
+
npm install
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
4. 启动开发环境
|
|
117
|
+
```bash
|
|
12
118
|
npm run dev
|
|
13
119
|
```
|
|
14
120
|
|
|
121
|
+
> 如果在创建时选择了「立即运行」,工具会自动执行启动命令。
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 🌐 技术栈官网链接
|
|
126
|
+
|
|
127
|
+
- [Vite](https://vitejs.dev/)
|
|
128
|
+
- [Vue 3](https://vuejs.org/)
|
|
129
|
+
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
130
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
131
|
+
- [Vue Router](https://router.vuejs.org/)
|
|
132
|
+
- [Pinia](https://pinia.vuejs.org/)
|
|
133
|
+
- [Axios](https://axios-http.com/)
|
|
134
|
+
- [Element Plus](https://element-plus.org/)
|
|
135
|
+
- [Vant](https://vant-contrib.gitee.io/vant/)
|
|
136
|
+
- [VueUse](https://vueuse.org/)
|
|
137
|
+
- [Lodash](https://lodash.com/)
|
|
138
|
+
- [Day.js](https://day.js.org/)
|
|
139
|
+
- [Tailwind CSS](https://tailwindcss.com/)
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 🔧 常见需要调整的地方(具体文件示例)
|
|
144
|
+
|
|
145
|
+
### 1️⃣ 接口请求地址
|
|
146
|
+
|
|
147
|
+
文件:`src/utils/request.ts` `src/utils/request.js`
|
|
148
|
+
```ts
|
|
149
|
+
import axios from 'axios';
|
|
150
|
+
|
|
151
|
+
const service = axios.create({
|
|
152
|
+
baseURL: import.meta.env.VITE_API_BASE_URL || '/api', // 修改为你的接口地址
|
|
153
|
+
timeout: 10000,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// 示例请求
|
|
157
|
+
export const getUserList = () => request.get('/users');
|
|
158
|
+
|
|
159
|
+
export default service;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> 🔹 根据实际业务修改 `baseURL` 和各个接口方法。
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### 2️⃣ 本地代理配置
|
|
167
|
+
|
|
168
|
+
文件:`vite.config.ts` `vite.config.js`
|
|
169
|
+
```ts
|
|
170
|
+
import { defineConfig } from 'vite';
|
|
171
|
+
import vue from '@vitejs/plugin-vue';
|
|
172
|
+
|
|
173
|
+
export default defineConfig({
|
|
174
|
+
plugins: [vue()],
|
|
175
|
+
server: {
|
|
176
|
+
proxy: {
|
|
177
|
+
'/api': {
|
|
178
|
+
target: 'http://localhost:3000', // 修改为后端服务地址
|
|
179
|
+
changeOrigin: true,
|
|
180
|
+
rewrite: (path) => path.replace(/^\/api/, ''),
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
> 🔹 如果接口路径前有 `/api` 前缀,可通过代理去掉
|
|
188
|
+
> 🔹 根据本地后端环境调整 `target`
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### 3️⃣ 路由结构
|
|
193
|
+
|
|
194
|
+
文件:`src/router/index.ts` `src/router/index.js`
|
|
195
|
+
```ts
|
|
196
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
197
|
+
import Home from '../views/Home.vue';
|
|
15
198
|
|
|
199
|
+
const routes = [
|
|
200
|
+
{ path: '/', name: 'Home', component: Home },
|
|
201
|
+
{ path: '/about', name: 'About', component: () => import('../views/About.vue') },
|
|
202
|
+
];
|
|
16
203
|
|
|
17
|
-
|
|
204
|
+
const router = createRouter({
|
|
205
|
+
history: createWebHistory(),
|
|
206
|
+
routes,
|
|
207
|
+
});
|
|
18
208
|
|
|
19
|
-
|
|
20
|
-
utils/request.ts
|
|
21
|
-
router/index.ts
|
|
209
|
+
export default router;
|
|
22
210
|
```
|
|
23
211
|
|
|
212
|
+
> 🔹 根据实际业务新增或删除路由,并修改页面组件路径
|
|
24
213
|
|
|
214
|
+
---
|
|
25
215
|
|
|
26
|
-
|
|
216
|
+
### 4️⃣ 页面内容与样式
|
|
27
217
|
|
|
28
|
-
|
|
29
|
-
|
|
218
|
+
文件示例:`src/views/Home.vue`
|
|
219
|
+
```vue
|
|
220
|
+
<template>
|
|
221
|
+
<div class="home-container">
|
|
222
|
+
<h1>欢迎来到项目首页</h1>
|
|
223
|
+
<p>这里可以根据业务需求修改页面内容和样式</p>
|
|
224
|
+
</div>
|
|
225
|
+
</template>
|
|
226
|
+
|
|
227
|
+
<script setup lang="ts">
|
|
228
|
+
// 可引入接口数据
|
|
229
|
+
// import { getUserList } from '@/api'
|
|
230
|
+
</script>
|
|
231
|
+
|
|
232
|
+
<style scoped>
|
|
233
|
+
.home-container {
|
|
234
|
+
padding: 20px;
|
|
235
|
+
}
|
|
236
|
+
</style>
|
|
30
237
|
```
|
|
31
238
|
|
|
32
|
-
|
|
239
|
+
> 🔹 根据实际业务修改 HTML、样式、以及调用接口逻辑
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 🎯 适用场景
|
|
244
|
+
|
|
245
|
+
- Vue 3 新手快速上手
|
|
246
|
+
- 后台管理系统
|
|
247
|
+
- 中小型 Web 项目
|
|
248
|
+
- 练手项目 / 毕设 / 实战项目
|
|
249
|
+
- 不想每次重复配置环境的开发者
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 📄 License
|
|
254
|
+
|
|
255
|
+
MIT License
|
|
256
|
+
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
// request.d.ts
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
/**
|
|
5
|
-
* HTTP 请求方法类型
|
|
6
|
-
*/
|
|
7
|
-
type HttpMethod =
|
|
8
|
-
| 'GET'
|
|
9
|
-
| 'POST'
|
|
10
|
-
| 'PUT'
|
|
11
|
-
| 'DELETE'
|
|
12
|
-
| 'PATCH'
|
|
13
|
-
| 'HEAD'
|
|
14
|
-
| 'OPTIONS'
|
|
15
|
-
| 'CONNECT'
|
|
16
|
-
| 'TRACE'
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 请求配置对象(Axios 风格)
|
|
20
|
-
*/
|
|
21
|
-
interface RequestConfig<T = any> {
|
|
22
|
-
/** 请求方法,默认 GET */
|
|
23
|
-
method?: HttpMethod
|
|
24
|
-
/** 请求 URL */
|
|
25
|
-
url: string
|
|
26
|
-
/** 基础 URL,会自动拼接到 url 前面 */
|
|
27
|
-
baseURL?: string
|
|
28
|
-
/** URL 查询参数(GET 请求的参数) */
|
|
29
|
-
params?: Record<string, any>
|
|
30
|
-
/** 请求体数据(POST、PUT、PATCH 等请求的参数) */
|
|
31
|
-
data?: T
|
|
32
|
-
/** 请求超时时间(毫秒),0 表示不超时 */
|
|
33
|
-
timeout?: number
|
|
34
|
-
/** 超时错误消息 */
|
|
35
|
-
timeoutErrorMessage?: string
|
|
36
|
-
/** 是否携带跨域凭证(cookies) */
|
|
37
|
-
withCredentials?: boolean
|
|
38
|
-
/** 响应数据类型 */
|
|
39
|
-
responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'
|
|
40
|
-
/** 响应编码 */
|
|
41
|
-
responseEncoding?: string
|
|
42
|
-
/** 自定义请求头 */
|
|
43
|
-
headers?: Record<string, string>
|
|
44
|
-
/** HTTP 基础认证 */
|
|
45
|
-
auth?: {
|
|
46
|
-
username: string
|
|
47
|
-
password: string
|
|
48
|
-
}
|
|
49
|
-
/** 代理配置 */
|
|
50
|
-
proxy?: {
|
|
51
|
-
host: string
|
|
52
|
-
port: number
|
|
53
|
-
protocol?: string
|
|
54
|
-
auth?: string
|
|
55
|
-
}
|
|
56
|
-
/** 响应内容最大长度 */
|
|
57
|
-
maxContentLength?: number
|
|
58
|
-
/** 请求体最大长度 */
|
|
59
|
-
maxBodyLength?: number
|
|
60
|
-
/** 最大重定向次数 */
|
|
61
|
-
maxRedirects?: number
|
|
62
|
-
/** Unix Socket 路径 */
|
|
63
|
-
socketPath?: string
|
|
64
|
-
/** Node.js HTTP Agent */
|
|
65
|
-
httpAgent?: any
|
|
66
|
-
/** Node.js HTTPS Agent */
|
|
67
|
-
httpsAgent?: any
|
|
68
|
-
/** 是否自动解压响应 */
|
|
69
|
-
decompress?: boolean
|
|
70
|
-
/** 自定义状态码验证函数 */
|
|
71
|
-
validateStatus?: (status: number) => boolean
|
|
72
|
-
/** 参数序列化函数 */
|
|
73
|
-
paramsSerializer?: (params: any) => string
|
|
74
|
-
/** 请求数据转换函数 */
|
|
75
|
-
transformRequest?: ((data: any, headers: any) => any) | Array<(data: any, headers: any) => any>
|
|
76
|
-
/** 响应数据转换函数 */
|
|
77
|
-
transformResponse?: ((data: any, headers: any, status: number) => any) | Array<(data: any, headers: any, status: number) => any>
|
|
78
|
-
/** 上传进度事件回调 */
|
|
79
|
-
onUploadProgress?: (progressEvent: any) => void
|
|
80
|
-
/** 下载进度事件回调 */
|
|
81
|
-
onDownloadProgress?: (progressEvent: any) => void
|
|
82
|
-
/** 取消令牌 */
|
|
83
|
-
cancelToken?: any
|
|
84
|
-
/** CSRF token cookie 名称 */
|
|
85
|
-
xsrfCookieName?: string
|
|
86
|
-
/** CSRF token header 名称 */
|
|
87
|
-
xsrfHeaderName?: string
|
|
88
|
-
/** 请求适配器 */
|
|
89
|
-
adapter?: (config: RequestConfig) => any
|
|
90
|
-
/** AbortSignal(用于取消请求) */
|
|
91
|
-
signal?: AbortSignal
|
|
92
|
-
/** 是否使用不安全的 HTTP 解析器 */
|
|
93
|
-
insecureHTTPParser?: boolean
|
|
94
|
-
/** 过渡性配置 */
|
|
95
|
-
transitional?: {
|
|
96
|
-
/** 是否静默 JSON 解析错误 */
|
|
97
|
-
silentJSONParsing?: boolean
|
|
98
|
-
/** 是否强制 JSON 解析 */
|
|
99
|
-
forcedJSONParsing?: boolean
|
|
100
|
-
/** 是否澄清超时错误 */
|
|
101
|
-
clarifyTimeoutError?: boolean
|
|
102
|
-
}
|
|
103
|
-
/** 代理连接回调 */
|
|
104
|
-
onProxyConnect?: (proxyReq: any, req: any, res: any) => void
|
|
105
|
-
/** 代理错误回调 */
|
|
106
|
-
onProxyError?: (err: Error, req: any, res: any) => void
|
|
107
|
-
/** 代理响应回调 */
|
|
108
|
-
onProxyResponse?: (proxyRes: any, req: any, res: any) => void
|
|
109
|
-
/** 方法名称(用于拦截器) */
|
|
110
|
-
methodName?: string
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Axios 响应对象
|
|
115
|
-
*/
|
|
116
|
-
interface AxiosResponse<T = any> {
|
|
117
|
-
/** 响应数据 */
|
|
118
|
-
data: T
|
|
119
|
-
/** HTTP 状态码 */
|
|
120
|
-
status: number
|
|
121
|
-
/** HTTP 状态文本 */
|
|
122
|
-
statusText: string
|
|
123
|
-
/** 响应头 */
|
|
124
|
-
headers: Record<string, string>
|
|
125
|
-
/** 请求配置 */
|
|
126
|
-
config: RequestConfig<T>
|
|
127
|
-
/** 原始请求对象 */
|
|
128
|
-
request?: XMLHttpRequest
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Axios 错误对象
|
|
133
|
-
*/
|
|
134
|
-
interface AxiosError<T = any> extends Error {
|
|
135
|
-
/** 错误代码 */
|
|
136
|
-
code?: string
|
|
137
|
-
/** 响应对象(如果收到响应) */
|
|
138
|
-
response?: AxiosResponse<T>
|
|
139
|
-
/** 请求配置 */
|
|
140
|
-
config?: RequestConfig<T>
|
|
141
|
-
/** 原始请求对象 */
|
|
142
|
-
request?: XMLHttpRequest
|
|
143
|
-
/** 是否为 Axios 错误 */
|
|
144
|
-
isAxiosError: boolean
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
export { }
|
|
148
|
-
|
|
File without changes
|