create-vite-vue 1.5.6 → 1.6.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/README.md +137 -91
- package/bin/index.js +60 -47
- package/package.json +1 -1
- package/template/base-js/README.md +154 -96
- package/template/base-js/package.json.tpl +3 -6
- package/template/base-ts/README.md +154 -96
- package/template/base-ts/package.json.tpl +6 -9
package/README.md
CHANGED
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
- 🌐 本地及网络访问启动日志显示
|
|
20
20
|
- 📝 自定义 Banner 插件显示项目信息
|
|
21
21
|
- 🎨 可选集成 Tailwind CSS(通过 postcss 配置)
|
|
22
|
-
- 🟢 支持多种包管理器:npm /
|
|
22
|
+
- 🟢 支持多种包管理器:npm / pnpm,可根据环境自动识别并使用
|
|
23
|
+
- 🔔 可选集成 Mitt(轻量事件总线,实现组件间解耦通信)
|
|
24
|
+
- 🛡️ 可选集成 mkcert 插件,实现本地 HTTPS 开发环境
|
|
23
25
|
|
|
24
26
|
---
|
|
25
27
|
|
|
@@ -34,6 +36,8 @@
|
|
|
34
36
|
🖥️ Element Plus / 📱 Vant
|
|
35
37
|
🧰 VueUse · Lodash · Day.js
|
|
36
38
|
🎨 Tailwind CSS
|
|
39
|
+
🔔 Mitt
|
|
40
|
+
🛡️ mkcert (本地 HTTPS)
|
|
37
41
|
|
|
38
42
|
---
|
|
39
43
|
|
|
@@ -59,46 +63,57 @@
|
|
|
59
63
|
|
|
60
64
|
## 📁 项目目录结构说明
|
|
61
65
|
|
|
62
|
-
project-name
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
│
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
│ ├─
|
|
71
|
-
|
|
72
|
-
│ ├─
|
|
73
|
-
|
|
74
|
-
│
|
|
75
|
-
|
|
76
|
-
│
|
|
77
|
-
|
|
78
|
-
│
|
|
79
|
-
|
|
80
|
-
│ ├─
|
|
81
|
-
|
|
82
|
-
├─
|
|
83
|
-
|
|
84
|
-
├─
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
66
|
+
> project-name
|
|
67
|
+
>
|
|
68
|
+
> ├─ public/ —— 公共静态资源目录
|
|
69
|
+
>
|
|
70
|
+
> │ └─ favicon.ico
|
|
71
|
+
>
|
|
72
|
+
> ├─ src/
|
|
73
|
+
>
|
|
74
|
+
> │ ├─ api/ —— 接口请求封装目录
|
|
75
|
+
>
|
|
76
|
+
> │ ├─ assets/ —— 图片、字体等静态资源
|
|
77
|
+
>
|
|
78
|
+
> │ ├─ components/ —— 公共组件目录
|
|
79
|
+
>
|
|
80
|
+
> │ ├─ router/ —— 路由配置(可选)
|
|
81
|
+
>
|
|
82
|
+
> │ ├─ stores/ —— Pinia 状态管理(可选)
|
|
83
|
+
>
|
|
84
|
+
> │ ├─ types/ —— 类型声明文件
|
|
85
|
+
>
|
|
86
|
+
> │ ├─ utils/ —— 工具方法、请求封装
|
|
87
|
+
>
|
|
88
|
+
> │ ├─ views/ —— 页面级组件(路由页面)
|
|
89
|
+
>
|
|
90
|
+
> │ │ └─ home/ —— 示例页面文件夹
|
|
91
|
+
>
|
|
92
|
+
> │ │ ├─ index.vue —— 默认首页 /home
|
|
93
|
+
>
|
|
94
|
+
> │ │ ├─ meta.json —— 页面 meta 信息
|
|
95
|
+
>
|
|
96
|
+
> │ │ └─ [id]/ —— 动态参数路由示例
|
|
97
|
+
>
|
|
98
|
+
> │ │ └─ [name].vue —— 路由 /home/:id/:name
|
|
99
|
+
>
|
|
100
|
+
> │ ├─ App.vue —— 根组件
|
|
101
|
+
>
|
|
102
|
+
> │ ├─ main.js / main.ts —— 项目启动入口
|
|
103
|
+
>
|
|
104
|
+
> │ └─ style.css —— 全局样式文件
|
|
105
|
+
>
|
|
106
|
+
> ├─ index.html —— 项目入口页面
|
|
107
|
+
>
|
|
108
|
+
> ├─ jsconfig.json / tsconfig.json —— 路径别名与编译配置
|
|
109
|
+
>
|
|
110
|
+
> ├─ package.json —— 项目依赖与脚本配置
|
|
111
|
+
>
|
|
112
|
+
> ├─ postcss.config.mjs —— Tailwind CSS 配置文件(可选)
|
|
113
|
+
>
|
|
114
|
+
> ├─ README.md —— 项目说明文档
|
|
115
|
+
>
|
|
116
|
+
> └─ vite.config.ts —— Vite 开发与构建配置
|
|
102
117
|
|
|
103
118
|
---
|
|
104
119
|
|
|
@@ -119,10 +134,10 @@ cd 项目名
|
|
|
119
134
|
|
|
120
135
|
3. 安装依赖
|
|
121
136
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
```bash
|
|
138
|
+
npm install
|
|
139
|
+
pnpm install
|
|
140
|
+
```
|
|
126
141
|
|
|
127
142
|
4. 启动开发环境
|
|
128
143
|
|
|
@@ -131,52 +146,6 @@ npm run dev
|
|
|
131
146
|
pnpm dev
|
|
132
147
|
```
|
|
133
148
|
|
|
134
|
-
> 如果在创建时选择了「立即运行」,工具会自动执行启动命令。使用yarn创建项目会报错,暂时未适配
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 🌐 技术栈官网链接
|
|
139
|
-
|
|
140
|
-
- [Vite](https://vitejs.dev/)
|
|
141
|
-
- [Vue 3](https://vuejs.org/)
|
|
142
|
-
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
143
|
-
- [TypeScript](https://www.typescriptlang.org/)
|
|
144
|
-
- [Vue Router](https://router.vuejs.org/)
|
|
145
|
-
- [Pinia](https://pinia.vuejs.org/)
|
|
146
|
-
- [Axios](https://axios-http.com/)
|
|
147
|
-
- [Element Plus](https://element-plus.org/)
|
|
148
|
-
- [Vant](https://vant-contrib.gitee.io/vant/)
|
|
149
|
-
- [VueUse](https://vueuse.org/)
|
|
150
|
-
- [Lodash](https://lodash.com/)
|
|
151
|
-
- [Day.js](https://day.js.org/)
|
|
152
|
-
- [Tailwind CSS](https://tailwindcss.com/)
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## 🟢 Node.js 版本管理(.nvmrc)
|
|
157
|
-
|
|
158
|
-
项目根目录中包含一个 **`.nvmrc`** 文件,用于指定当前项目推荐使用的**Node.js 版本**。这样可以保证不同开发者或不同机器运行项目时使用一致的 Node环境,避免依赖问题。
|
|
159
|
-
|
|
160
|
-
### 使用 nvm 切换 Node 版本
|
|
161
|
-
|
|
162
|
-
如果你安装了 **nvm(Node Version Manager)**,进入项目目录后执行:
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
nvm use
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
> nvm 会自动读取 `.nvmrc` 文件中的 Node 版本并切换。
|
|
169
|
-
|
|
170
|
-
### Windows 可能出现的问题
|
|
171
|
-
|
|
172
|
-
在 **Windows PowerShell** 中,`nvm use` 有时不会自动读取`.nvmrc`,可能会报错或无法切换版本。
|
|
173
|
-
|
|
174
|
-
如果出现这种情况,可以执行:
|
|
175
|
-
|
|
176
|
-
```powershell
|
|
177
|
-
nvm use $(Get-Content .nvmrc)
|
|
178
|
-
```
|
|
179
|
-
|
|
180
149
|
---
|
|
181
150
|
|
|
182
151
|
## 🔧 常见需要调整的地方(具体文件示例)
|
|
@@ -293,6 +262,64 @@ console.log(route.params.name)
|
|
|
293
262
|
|
|
294
263
|
---
|
|
295
264
|
|
|
265
|
+
### 5️⃣ Mitt 事件总线使用示例
|
|
266
|
+
|
|
267
|
+
#### 封装事件总线
|
|
268
|
+
|
|
269
|
+
文件:`src/utils/eventBus.ts`
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import mitt from 'mitt'
|
|
273
|
+
|
|
274
|
+
type Events = {
|
|
275
|
+
userLogin: { name: string },
|
|
276
|
+
userLogout: null
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const emitter = mitt<Events>()
|
|
280
|
+
|
|
281
|
+
export default emitter
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### 使用示例
|
|
285
|
+
|
|
286
|
+
##### 组件 A(发送事件)
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
<script setup lang="ts">
|
|
290
|
+
import eventBus from '@/utils/eventBus'
|
|
291
|
+
|
|
292
|
+
function login() {
|
|
293
|
+
eventBus.emit('userLogin', { name: '张三' })
|
|
294
|
+
}
|
|
295
|
+
</script>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
##### 组件 B(接收事件)
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
<script setup lang="ts">
|
|
302
|
+
import { onMounted, onUnmounted } from 'vue'
|
|
303
|
+
import eventBus from '@/utils/eventBus'
|
|
304
|
+
|
|
305
|
+
function handleLogin(payload: { name: string }) {
|
|
306
|
+
console.log('用户登录:', payload.name)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
onMounted(() => {
|
|
310
|
+
eventBus.on('userLogin', handleLogin)
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
onUnmounted(() => {
|
|
314
|
+
eventBus.off('userLogin', handleLogin)
|
|
315
|
+
})
|
|
316
|
+
</script>
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
> 🔹 Mitt 事件总线轻量高效,适合组件间解耦通信,替代父子传递 props / emit 或 Vuex/Pinia 中的小型事件场景。
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
296
323
|
## 🎯 适用场景
|
|
297
324
|
|
|
298
325
|
- Vue 3 新手快速上手
|
|
@@ -303,6 +330,25 @@ console.log(route.params.name)
|
|
|
303
330
|
|
|
304
331
|
---
|
|
305
332
|
|
|
333
|
+
## 🌐 技术栈官网链接
|
|
334
|
+
|
|
335
|
+
- [Vite | 下一代的前端工具链](https://cn.vitejs.dev/)
|
|
336
|
+
- [Vue.js - 渐进式 JavaScript 框架 | Vue.js](https://cn.vuejs.org/)
|
|
337
|
+
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
338
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
339
|
+
- [Vue Router | Vue.js 的官方路由](https://router.vuejs.org/zh/)
|
|
340
|
+
- [Pinia | The intuitive store for Vue.js](https://pinia.vuejs.org/zh/)
|
|
341
|
+
- [Axios](https://www.axios-http.cn/)
|
|
342
|
+
- [Element Plus | 一个 Vue 3 UI 框架](https://element-plus.org/zh-CN/)
|
|
343
|
+
- [Vant 4 - 轻量、可定制的移动端组件库](https://vant-ui.github.io/vant/#/zh-CN)
|
|
344
|
+
- [VueUse](https://vueuse.pages.dev/)
|
|
345
|
+
- [Lodash](https://www.lodashjs.com/)
|
|
346
|
+
- [Day.js](https://day.js.org/)
|
|
347
|
+
- [Tailwind CSS](https://tailwindcss.com/)
|
|
348
|
+
- [Mitt](https://github.com/developit/mitt)
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
306
352
|
## 📄 License
|
|
307
353
|
|
|
308
354
|
MIT License
|
package/bin/index.js
CHANGED
|
@@ -41,10 +41,6 @@ const pkgCommands = {
|
|
|
41
41
|
install: 'npm install',
|
|
42
42
|
dev: 'npm run dev'
|
|
43
43
|
},
|
|
44
|
-
yarn: {
|
|
45
|
-
install: 'yarn',
|
|
46
|
-
dev: 'yarn dev'
|
|
47
|
-
},
|
|
48
44
|
pnpm: {
|
|
49
45
|
install: 'pnpm install',
|
|
50
46
|
dev: 'pnpm dev'
|
|
@@ -104,7 +100,9 @@ const pkgCommands = {
|
|
|
104
100
|
{ title: 'VueUse(实用 Composition API)', value: 'vueuse' },
|
|
105
101
|
{ title: 'Lodash(工具库)', value: 'lodash' },
|
|
106
102
|
{ title: 'Day.js(日期处理)', value: 'dayjs' },
|
|
107
|
-
{ title: 'Tailwind CSS(原子化 CSS)', value: 'tailwind' }
|
|
103
|
+
{ title: 'Tailwind CSS(原子化 CSS)', value: 'tailwind' },
|
|
104
|
+
{ title: 'mitt(事件总线)', value: 'mitt' },
|
|
105
|
+
{ title: 'HTTPS(mkcert)', value: 'https' }
|
|
108
106
|
]
|
|
109
107
|
})
|
|
110
108
|
|
|
@@ -117,7 +115,7 @@ const pkgCommands = {
|
|
|
117
115
|
}
|
|
118
116
|
|
|
119
117
|
const extraPlugins = featureList?.filter(v =>
|
|
120
|
-
['vueuse', 'lodash', 'dayjs', 'tailwind'].includes(v)
|
|
118
|
+
['vueuse', 'lodash', 'dayjs', 'tailwind', 'mitt', 'https'].includes(v)
|
|
121
119
|
) || []
|
|
122
120
|
|
|
123
121
|
// 询问是否开启自动路由
|
|
@@ -134,6 +132,8 @@ const pkgCommands = {
|
|
|
134
132
|
autoRoute = enableAutoRoute
|
|
135
133
|
}
|
|
136
134
|
|
|
135
|
+
const enableHttps = featureList?.includes('https') || false
|
|
136
|
+
|
|
137
137
|
// 3️⃣ 是否立即运行 dev
|
|
138
138
|
const { runDev } = await prompts({
|
|
139
139
|
type: 'select',
|
|
@@ -253,7 +253,7 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
253
253
|
}
|
|
254
254
|
if(features.axios) optionalDeps['axios'] = '^1.13.6'
|
|
255
255
|
if(features.ui.includes('element')) {
|
|
256
|
-
optionalDeps['element-plus'] = '^2.13.
|
|
256
|
+
optionalDeps['element-plus'] = '^2.13.5'
|
|
257
257
|
optionalDeps['@element-plus/icons-vue'] = '^2.3.2'
|
|
258
258
|
}
|
|
259
259
|
if(features.ui.includes('vant')) {
|
|
@@ -261,13 +261,15 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
261
261
|
}
|
|
262
262
|
// 增强插件依赖
|
|
263
263
|
if(extraPlugins.includes('vueuse')) optionalDeps['@vueuse/core'] = '^14.2.1'
|
|
264
|
-
if(extraPlugins.includes('dayjs')) optionalDeps['dayjs'] = '^1.11.
|
|
264
|
+
if(extraPlugins.includes('dayjs')) optionalDeps['dayjs'] = '^1.11.20'
|
|
265
265
|
if(extraPlugins.includes('lodash')) optionalDeps['lodash'] = '^4.17.23'
|
|
266
266
|
if(extraPlugins.includes('tailwind')) {
|
|
267
|
-
optionalDeps['tailwindcss'] = '^4.2.
|
|
268
|
-
optionalDeps['@tailwindcss/postcss'] = '^4.2.
|
|
267
|
+
optionalDeps['tailwindcss'] = '^4.2.2'
|
|
268
|
+
optionalDeps['@tailwindcss/postcss'] = '^4.2.2'
|
|
269
269
|
optionalDeps['postcss'] = '^8.5.8'
|
|
270
270
|
}
|
|
271
|
+
if(extraPlugins.includes('mitt')) optionalDeps['mitt'] = '^3.0.1'
|
|
272
|
+
if(enableHttps) optionalDeps['vite-plugin-mkcert'] = '^1.17.10'
|
|
271
273
|
if(autoRoute) optionalDeps['vite-plugin-pages'] = '^0.33.3'
|
|
272
274
|
|
|
273
275
|
let depsStr = ''
|
|
@@ -284,19 +286,48 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
284
286
|
fs.unlinkSync(pkgTpl)
|
|
285
287
|
}
|
|
286
288
|
|
|
287
|
-
// 8️⃣
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
289
|
+
// 8️⃣ 配置 vite.config.js / vite.config.ts(自动路由 + HTTPS)
|
|
290
|
+
const viteConfigPath = path.join(
|
|
291
|
+
targetDir,
|
|
292
|
+
`vite.config.${language === 'ts' ? 'ts' : 'js'}`
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if(fs.existsSync(viteConfigPath)) {
|
|
296
|
+
let viteConfig = fs.readFileSync(viteConfigPath, 'utf-8')
|
|
297
|
+
|
|
298
|
+
// ===== mkcert 插件 =====
|
|
299
|
+
if(enableHttps) {
|
|
300
|
+
if(!viteConfig.includes("vite-plugin-mkcert")) {
|
|
301
|
+
viteConfig = viteConfig.replace(
|
|
302
|
+
/(import .*?from .*?\n)/,
|
|
303
|
+
`$1import mkcert from 'vite-plugin-mkcert'\n`
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if(!viteConfig.includes("mkcert(")) {
|
|
308
|
+
viteConfig = viteConfig.replace(
|
|
309
|
+
/plugins:\s*\[/,
|
|
310
|
+
`plugins: [
|
|
311
|
+
mkcert(),`
|
|
312
|
+
)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ===== 自动路由 =====
|
|
317
|
+
if(autoRoute) {
|
|
292
318
|
if(!viteConfig.includes("import fs from 'fs'")) {
|
|
293
319
|
viteConfig = `import fs from 'fs'\n${viteConfig}`
|
|
294
320
|
}
|
|
295
|
-
// 确保顶部 import Pages
|
|
296
321
|
if(!viteConfig.includes("import Pages from 'vite-plugin-pages'")) {
|
|
297
|
-
viteConfig = viteConfig.replace(
|
|
322
|
+
viteConfig = viteConfig.replace(
|
|
323
|
+
/(import .*?from .*?\n)/,
|
|
324
|
+
`$1import Pages from 'vite-plugin-pages'\n`
|
|
325
|
+
)
|
|
298
326
|
}
|
|
299
|
-
viteConfig
|
|
327
|
+
if(!viteConfig.includes("Pages({")) {
|
|
328
|
+
viteConfig = viteConfig.replace(
|
|
329
|
+
/plugins:\s*\[/,
|
|
330
|
+
`plugins: [
|
|
300
331
|
Pages({
|
|
301
332
|
dirs: 'src/views',
|
|
302
333
|
extensions: ['vue'],
|
|
@@ -316,33 +347,13 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
|
|
316
347
|
}
|
|
317
348
|
return { ...route }
|
|
318
349
|
}
|
|
319
|
-
}),`
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// 创建 Home/meta.json
|
|
324
|
-
const homeMetaPath = path.join(targetDir, 'src/views/home/meta.json')
|
|
325
|
-
if(!fs.existsSync(homeMetaPath)) {
|
|
326
|
-
fs.writeFileSync(homeMetaPath, JSON.stringify({ title: '首页' }, null, 2))
|
|
327
|
-
}
|
|
328
|
-
if(language === 'ts') {
|
|
329
|
-
// 生成 types 目录
|
|
330
|
-
const typesDir = path.join(targetDir, 'src/types')
|
|
331
|
-
if(!fs.existsSync(typesDir)) fs.mkdirSync(typesDir, { recursive: true })
|
|
332
|
-
|
|
333
|
-
// 创建 vite-plugin-pages.d.ts
|
|
334
|
-
const vitePagesDtsPath = path.join(typesDir, 'vite-plugin-pages.d.ts')
|
|
335
|
-
const vitePagesDtsContent = `declare module '~pages' {
|
|
336
|
-
import type { RouteRecordRaw } from 'vue-router'
|
|
337
|
-
const routes: RouteRecordRaw[]
|
|
338
|
-
export default routes
|
|
339
|
-
}
|
|
340
|
-
`
|
|
341
|
-
fs.writeFileSync(vitePagesDtsPath, vitePagesDtsContent)
|
|
350
|
+
}),`
|
|
351
|
+
)
|
|
352
|
+
}
|
|
342
353
|
}
|
|
343
354
|
|
|
355
|
+
fs.writeFileSync(viteConfigPath, viteConfig)
|
|
344
356
|
}
|
|
345
|
-
|
|
346
357
|
// 9️⃣ 替换 router/index.js
|
|
347
358
|
if(features.router) {
|
|
348
359
|
const routerIndexPath = path.join(targetDir, `src/router/index.${language === 'ts' ? 'ts' : 'js'}`)
|
|
@@ -391,8 +402,6 @@ export default createRouter({
|
|
|
391
402
|
|
|
392
403
|
if(pkgManager === 'pnpm') {
|
|
393
404
|
installCmd = 'pnpm install'
|
|
394
|
-
} else if(pkgManager === 'yarn') {
|
|
395
|
-
installCmd = 'yarn'
|
|
396
405
|
} else {
|
|
397
406
|
installCmd = 'npm install'
|
|
398
407
|
}
|
|
@@ -402,6 +411,9 @@ export default createRouter({
|
|
|
402
411
|
// 1️⃣1️⃣ 运行 dev
|
|
403
412
|
if(runDev) {
|
|
404
413
|
console.log('🚀 启动开发服务器...')
|
|
414
|
+
if(enableHttps) {
|
|
415
|
+
console.log('🔐 首次启用 HTTPS 会自动生成证书,请稍等...')
|
|
416
|
+
}
|
|
405
417
|
execSync(pkgCommands[pkgManager].dev, {
|
|
406
418
|
cwd: targetDir,
|
|
407
419
|
stdio: 'inherit'
|
|
@@ -409,7 +421,10 @@ export default createRouter({
|
|
|
409
421
|
} else {
|
|
410
422
|
console.log(`\n✅ 项目创建完成`)
|
|
411
423
|
console.log(`👉 cd ${projectName}`)
|
|
412
|
-
console.log(`👉 ${pkgCommands[pkgManager].dev}
|
|
424
|
+
console.log(`👉 ${pkgCommands[pkgManager].dev}`)
|
|
425
|
+
if(enableHttps) {
|
|
426
|
+
console.log('🔐 首次启用 HTTPS 会自动生成证书,请稍等...\n')
|
|
427
|
+
}
|
|
413
428
|
}
|
|
414
429
|
})()
|
|
415
430
|
|
|
@@ -417,11 +432,9 @@ function detectPackageManager () {
|
|
|
417
432
|
const userAgent = process.env.npm_config_user_agent || ''
|
|
418
433
|
|
|
419
434
|
if(userAgent.startsWith('pnpm')) return 'pnpm'
|
|
420
|
-
if(userAgent.startsWith('yarn')) return 'yarn'
|
|
421
435
|
if(userAgent.startsWith('npm')) return 'npm'
|
|
422
436
|
|
|
423
437
|
if(fs.existsSync('pnpm-lock.yaml')) return 'pnpm'
|
|
424
|
-
if(fs.existsSync('yarn.lock')) return 'yarn'
|
|
425
438
|
|
|
426
439
|
return 'npm'
|
|
427
440
|
}
|
package/package.json
CHANGED
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
- 🌐 本地及网络访问启动日志显示
|
|
20
20
|
- 📝 自定义 Banner 插件显示项目信息
|
|
21
21
|
- 🎨 可选集成 Tailwind CSS(通过 postcss 配置)
|
|
22
|
+
- 🟢 支持多种包管理器:npm / pnpm,可根据环境自动识别并使用
|
|
23
|
+
- 🔔 可选集成 Mitt(轻量事件总线,实现组件间解耦通信)
|
|
24
|
+
- 🛡️ 可选集成 mkcert 插件,实现本地 HTTPS 开发环境
|
|
22
25
|
|
|
23
26
|
---
|
|
24
27
|
|
|
@@ -33,6 +36,8 @@
|
|
|
33
36
|
🖥️ Element Plus / 📱 Vant
|
|
34
37
|
🧰 VueUse · Lodash · Day.js
|
|
35
38
|
🎨 Tailwind CSS
|
|
39
|
+
🔔 Mitt
|
|
40
|
+
🛡️ mkcert (本地 HTTPS)
|
|
36
41
|
|
|
37
42
|
---
|
|
38
43
|
|
|
@@ -58,126 +63,97 @@
|
|
|
58
63
|
|
|
59
64
|
## 📁 项目目录结构说明
|
|
60
65
|
|
|
61
|
-
project-name
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
│
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
│ ├─
|
|
70
|
-
|
|
71
|
-
│ ├─
|
|
72
|
-
|
|
73
|
-
│
|
|
74
|
-
|
|
75
|
-
│
|
|
76
|
-
|
|
77
|
-
│
|
|
78
|
-
|
|
79
|
-
│ ├─
|
|
80
|
-
|
|
81
|
-
├─
|
|
82
|
-
|
|
83
|
-
├─
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
66
|
+
> project-name
|
|
67
|
+
>
|
|
68
|
+
> ├─ public/ —— 公共静态资源目录
|
|
69
|
+
>
|
|
70
|
+
> │ └─ favicon.ico
|
|
71
|
+
>
|
|
72
|
+
> ├─ src/
|
|
73
|
+
>
|
|
74
|
+
> │ ├─ api/ —— 接口请求封装目录
|
|
75
|
+
>
|
|
76
|
+
> │ ├─ assets/ —— 图片、字体等静态资源
|
|
77
|
+
>
|
|
78
|
+
> │ ├─ components/ —— 公共组件目录
|
|
79
|
+
>
|
|
80
|
+
> │ ├─ router/ —— 路由配置(可选)
|
|
81
|
+
>
|
|
82
|
+
> │ ├─ stores/ —— Pinia 状态管理(可选)
|
|
83
|
+
>
|
|
84
|
+
> │ ├─ types/ —— 类型声明文件
|
|
85
|
+
>
|
|
86
|
+
> │ ├─ utils/ —— 工具方法、请求封装
|
|
87
|
+
>
|
|
88
|
+
> │ ├─ views/ —— 页面级组件(路由页面)
|
|
89
|
+
>
|
|
90
|
+
> │ │ └─ home/ —— 示例页面文件夹
|
|
91
|
+
>
|
|
92
|
+
> │ │ ├─ index.vue —— 默认首页 /home
|
|
93
|
+
>
|
|
94
|
+
> │ │ ├─ meta.json —— 页面 meta 信息
|
|
95
|
+
>
|
|
96
|
+
> │ │ └─ [id]/ —— 动态参数路由示例
|
|
97
|
+
>
|
|
98
|
+
> │ │ └─ [name].vue —— 路由 /home/:id/:name
|
|
99
|
+
>
|
|
100
|
+
> │ ├─ App.vue —— 根组件
|
|
101
|
+
>
|
|
102
|
+
> │ ├─ main.js / main.ts —— 项目启动入口
|
|
103
|
+
>
|
|
104
|
+
> │ └─ style.css —— 全局样式文件
|
|
105
|
+
>
|
|
106
|
+
> ├─ index.html —— 项目入口页面
|
|
107
|
+
>
|
|
108
|
+
> ├─ jsconfig.json / tsconfig.json —— 路径别名与编译配置
|
|
109
|
+
>
|
|
110
|
+
> ├─ package.json —— 项目依赖与脚本配置
|
|
111
|
+
>
|
|
112
|
+
> ├─ postcss.config.mjs —— Tailwind CSS 配置文件(可选)
|
|
113
|
+
>
|
|
114
|
+
> ├─ README.md —— 项目说明文档
|
|
115
|
+
>
|
|
116
|
+
> └─ vite.config.ts —— Vite 开发与构建配置
|
|
101
117
|
|
|
102
118
|
---
|
|
103
119
|
|
|
104
|
-
## ⚙️
|
|
120
|
+
## ⚙️ 使用方式(多包管理器支持)
|
|
105
121
|
|
|
106
122
|
1. 创建项目
|
|
123
|
+
|
|
107
124
|
```bash
|
|
108
125
|
npm create vite-vue@latest
|
|
126
|
+
pnpm create vite-vue@latest
|
|
109
127
|
```
|
|
110
128
|
|
|
111
129
|
2. 进入项目目录
|
|
130
|
+
|
|
112
131
|
```bash
|
|
113
132
|
cd 项目名
|
|
114
133
|
```
|
|
115
134
|
|
|
116
|
-
3. 安装依赖
|
|
135
|
+
3. 安装依赖
|
|
136
|
+
|
|
117
137
|
```bash
|
|
118
138
|
npm install
|
|
139
|
+
pnpm install
|
|
119
140
|
```
|
|
120
141
|
|
|
121
142
|
4. 启动开发环境
|
|
143
|
+
|
|
122
144
|
```bash
|
|
123
145
|
npm run dev
|
|
146
|
+
pnpm dev
|
|
124
147
|
```
|
|
125
148
|
|
|
126
|
-
> 如果在创建时选择了「立即运行」,工具会自动执行启动命令。
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## 🌐 技术栈官网链接
|
|
131
|
-
|
|
132
|
-
- [Vite](https://vitejs.dev/)
|
|
133
|
-
- [Vue 3](https://vuejs.org/)
|
|
134
|
-
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
135
|
-
- [TypeScript](https://www.typescriptlang.org/)
|
|
136
|
-
- [Vue Router](https://router.vuejs.org/)
|
|
137
|
-
- [Pinia](https://pinia.vuejs.org/)
|
|
138
|
-
- [Axios](https://axios-http.com/)
|
|
139
|
-
- [Element Plus](https://element-plus.org/)
|
|
140
|
-
- [Vant](https://vant-contrib.gitee.io/vant/)
|
|
141
|
-
- [VueUse](https://vueuse.org/)
|
|
142
|
-
- [Lodash](https://lodash.com/)
|
|
143
|
-
- [Day.js](https://day.js.org/)
|
|
144
|
-
- [Tailwind CSS](https://tailwindcss.com/)
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## 🟢 Node.js 版本管理(.nvmrc)
|
|
149
|
-
|
|
150
|
-
项目根目录中包含一个 **`.nvmrc`** 文件,用于指定当前项目推荐使用的**Node.js 版本**。这样可以保证不同开发者或不同机器运行项目时使用一致的 Node环境,避免依赖问题。
|
|
151
|
-
|
|
152
|
-
### 使用 nvm 切换 Node 版本
|
|
153
|
-
|
|
154
|
-
如果你安装了 **nvm(Node Version Manager)**,进入项目目录后执行:
|
|
155
|
-
|
|
156
|
-
``` bash
|
|
157
|
-
nvm use
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
nvm 会自动读取 `.nvmrc` 文件中的 Node 版本并切换。
|
|
161
|
-
|
|
162
|
-
### Windows 可能出现的问题
|
|
163
|
-
|
|
164
|
-
在 **Windows PowerShell** 中,`nvm use` 有时不会自动读取`.nvmrc`,可能会报错或无法切换版本。
|
|
165
|
-
|
|
166
|
-
如果出现这种情况,可以执行:
|
|
167
|
-
|
|
168
|
-
``` powershell
|
|
169
|
-
nvm use $(Get-Content .nvmrc)
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
该命令会读取 `.nvmrc` 文件内容并手动切换 Node 版本。
|
|
173
|
-
|
|
174
149
|
---
|
|
175
150
|
|
|
176
151
|
## 🔧 常见需要调整的地方(具体文件示例)
|
|
177
152
|
|
|
178
153
|
### 1️⃣ 接口请求地址
|
|
179
154
|
|
|
180
|
-
文件:`src/utils/request.ts`
|
|
155
|
+
文件:`src/utils/request.ts` / `src/utils/request.js`
|
|
156
|
+
|
|
181
157
|
```ts
|
|
182
158
|
import axios from 'axios';
|
|
183
159
|
|
|
@@ -187,7 +163,7 @@ const service = axios.create({
|
|
|
187
163
|
});
|
|
188
164
|
|
|
189
165
|
// 示例请求
|
|
190
|
-
export const getUserList = () =>
|
|
166
|
+
export const getUserList = () => service.get('/users');
|
|
191
167
|
|
|
192
168
|
export default service;
|
|
193
169
|
```
|
|
@@ -198,7 +174,8 @@ export default service;
|
|
|
198
174
|
|
|
199
175
|
### 2️⃣ 本地代理配置
|
|
200
176
|
|
|
201
|
-
文件:`vite.config.ts`
|
|
177
|
+
文件:`vite.config.ts` / `vite.config.js`
|
|
178
|
+
|
|
202
179
|
```ts
|
|
203
180
|
import { defineConfig } from 'vite';
|
|
204
181
|
import vue from '@vitejs/plugin-vue';
|
|
@@ -224,7 +201,8 @@ export default defineConfig({
|
|
|
224
201
|
|
|
225
202
|
### 3️⃣ 路由结构(支持动态参数)
|
|
226
203
|
|
|
227
|
-
文件:`src/router/index.ts`
|
|
204
|
+
文件:`src/router/index.ts` / `src/router/index.js`
|
|
205
|
+
|
|
228
206
|
```ts
|
|
229
207
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
230
208
|
import routes from '~pages' // 自动生成的路由
|
|
@@ -237,14 +215,16 @@ const router = createRouter({
|
|
|
237
215
|
export default router
|
|
238
216
|
```
|
|
239
217
|
|
|
240
|
-
>
|
|
218
|
+
> 页面文件夹结构示例:
|
|
219
|
+
|
|
241
220
|
```text
|
|
242
221
|
src/views/home/
|
|
243
222
|
├─ index.vue -> /home
|
|
244
223
|
└─ [id]/[name].vue -> /home/:id/:name
|
|
245
224
|
```
|
|
246
225
|
|
|
247
|
-
>
|
|
226
|
+
> 获取路由参数:
|
|
227
|
+
|
|
248
228
|
```ts
|
|
249
229
|
import { useRoute } from 'vue-router'
|
|
250
230
|
const route = useRoute()
|
|
@@ -257,6 +237,7 @@ console.log(route.params.name)
|
|
|
257
237
|
### 4️⃣ 页面内容与样式
|
|
258
238
|
|
|
259
239
|
文件示例:`src/views/home/index.vue`
|
|
240
|
+
|
|
260
241
|
```vue
|
|
261
242
|
<template>
|
|
262
243
|
<div class="home-container">
|
|
@@ -281,6 +262,64 @@ console.log(route.params.name)
|
|
|
281
262
|
|
|
282
263
|
---
|
|
283
264
|
|
|
265
|
+
### 5️⃣ Mitt 事件总线使用示例
|
|
266
|
+
|
|
267
|
+
#### 封装事件总线
|
|
268
|
+
|
|
269
|
+
文件:`src/utils/eventBus.ts`
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import mitt from 'mitt'
|
|
273
|
+
|
|
274
|
+
type Events = {
|
|
275
|
+
userLogin: { name: string },
|
|
276
|
+
userLogout: null
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const emitter = mitt<Events>()
|
|
280
|
+
|
|
281
|
+
export default emitter
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### 使用示例
|
|
285
|
+
|
|
286
|
+
##### 组件 A(发送事件)
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
<script setup lang="ts">
|
|
290
|
+
import eventBus from '@/utils/eventBus'
|
|
291
|
+
|
|
292
|
+
function login() {
|
|
293
|
+
eventBus.emit('userLogin', { name: '张三' })
|
|
294
|
+
}
|
|
295
|
+
</script>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
##### 组件 B(接收事件)
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
<script setup lang="ts">
|
|
302
|
+
import { onMounted, onUnmounted } from 'vue'
|
|
303
|
+
import eventBus from '@/utils/eventBus'
|
|
304
|
+
|
|
305
|
+
function handleLogin(payload: { name: string }) {
|
|
306
|
+
console.log('用户登录:', payload.name)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
onMounted(() => {
|
|
310
|
+
eventBus.on('userLogin', handleLogin)
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
onUnmounted(() => {
|
|
314
|
+
eventBus.off('userLogin', handleLogin)
|
|
315
|
+
})
|
|
316
|
+
</script>
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
> 🔹 Mitt 事件总线轻量高效,适合组件间解耦通信,替代父子传递 props / emit 或 Vuex/Pinia 中的小型事件场景。
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
284
323
|
## 🎯 适用场景
|
|
285
324
|
|
|
286
325
|
- Vue 3 新手快速上手
|
|
@@ -291,6 +330,25 @@ console.log(route.params.name)
|
|
|
291
330
|
|
|
292
331
|
---
|
|
293
332
|
|
|
333
|
+
## 🌐 技术栈官网链接
|
|
334
|
+
|
|
335
|
+
- [Vite | 下一代的前端工具链](https://cn.vitejs.dev/)
|
|
336
|
+
- [Vue.js - 渐进式 JavaScript 框架 | Vue.js](https://cn.vuejs.org/)
|
|
337
|
+
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
338
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
339
|
+
- [Vue Router | Vue.js 的官方路由](https://router.vuejs.org/zh/)
|
|
340
|
+
- [Pinia | The intuitive store for Vue.js](https://pinia.vuejs.org/zh/)
|
|
341
|
+
- [Axios](https://www.axios-http.cn/)
|
|
342
|
+
- [Element Plus | 一个 Vue 3 UI 框架](https://element-plus.org/zh-CN/)
|
|
343
|
+
- [Vant 4 - 轻量、可定制的移动端组件库](https://vant-ui.github.io/vant/#/zh-CN)
|
|
344
|
+
- [VueUse](https://vueuse.pages.dev/)
|
|
345
|
+
- [Lodash](https://www.lodashjs.com/)
|
|
346
|
+
- [Day.js](https://day.js.org/)
|
|
347
|
+
- [Tailwind CSS](https://tailwindcss.com/)
|
|
348
|
+
- [Mitt](https://github.com/developit/mitt)
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
294
352
|
## 📄 License
|
|
295
353
|
|
|
296
354
|
MIT License
|
|
@@ -11,13 +11,10 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"less": "^4.5.1",
|
|
13
13
|
"tslib": "^2.8.1",
|
|
14
|
-
"vue": "^3.5.
|
|
14
|
+
"vue": "^3.5.30"__OPTIONAL_DEP__
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
18
|
-
"vite": "^8.0.
|
|
19
|
-
},
|
|
20
|
-
"overrides": {
|
|
21
|
-
"vite": "^8.0.0-beta.13"
|
|
17
|
+
"@vitejs/plugin-vue": "^6.0.5",
|
|
18
|
+
"vite": "^8.0.1"
|
|
22
19
|
}
|
|
23
20
|
}
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
- 🌐 本地及网络访问启动日志显示
|
|
20
20
|
- 📝 自定义 Banner 插件显示项目信息
|
|
21
21
|
- 🎨 可选集成 Tailwind CSS(通过 postcss 配置)
|
|
22
|
+
- 🟢 支持多种包管理器:npm / pnpm,可根据环境自动识别并使用
|
|
23
|
+
- 🔔 可选集成 Mitt(轻量事件总线,实现组件间解耦通信)
|
|
24
|
+
- 🛡️ 可选集成 mkcert 插件,实现本地 HTTPS 开发环境
|
|
22
25
|
|
|
23
26
|
---
|
|
24
27
|
|
|
@@ -33,6 +36,8 @@
|
|
|
33
36
|
🖥️ Element Plus / 📱 Vant
|
|
34
37
|
🧰 VueUse · Lodash · Day.js
|
|
35
38
|
🎨 Tailwind CSS
|
|
39
|
+
🔔 Mitt
|
|
40
|
+
🛡️ mkcert (本地 HTTPS)
|
|
36
41
|
|
|
37
42
|
---
|
|
38
43
|
|
|
@@ -58,126 +63,97 @@
|
|
|
58
63
|
|
|
59
64
|
## 📁 项目目录结构说明
|
|
60
65
|
|
|
61
|
-
project-name
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
│
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
│ ├─
|
|
70
|
-
|
|
71
|
-
│ ├─
|
|
72
|
-
|
|
73
|
-
│
|
|
74
|
-
|
|
75
|
-
│
|
|
76
|
-
|
|
77
|
-
│
|
|
78
|
-
|
|
79
|
-
│ ├─
|
|
80
|
-
|
|
81
|
-
├─
|
|
82
|
-
|
|
83
|
-
├─
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
66
|
+
> project-name
|
|
67
|
+
>
|
|
68
|
+
> ├─ public/ —— 公共静态资源目录
|
|
69
|
+
>
|
|
70
|
+
> │ └─ favicon.ico
|
|
71
|
+
>
|
|
72
|
+
> ├─ src/
|
|
73
|
+
>
|
|
74
|
+
> │ ├─ api/ —— 接口请求封装目录
|
|
75
|
+
>
|
|
76
|
+
> │ ├─ assets/ —— 图片、字体等静态资源
|
|
77
|
+
>
|
|
78
|
+
> │ ├─ components/ —— 公共组件目录
|
|
79
|
+
>
|
|
80
|
+
> │ ├─ router/ —— 路由配置(可选)
|
|
81
|
+
>
|
|
82
|
+
> │ ├─ stores/ —— Pinia 状态管理(可选)
|
|
83
|
+
>
|
|
84
|
+
> │ ├─ types/ —— 类型声明文件
|
|
85
|
+
>
|
|
86
|
+
> │ ├─ utils/ —— 工具方法、请求封装
|
|
87
|
+
>
|
|
88
|
+
> │ ├─ views/ —— 页面级组件(路由页面)
|
|
89
|
+
>
|
|
90
|
+
> │ │ └─ home/ —— 示例页面文件夹
|
|
91
|
+
>
|
|
92
|
+
> │ │ ├─ index.vue —— 默认首页 /home
|
|
93
|
+
>
|
|
94
|
+
> │ │ ├─ meta.json —— 页面 meta 信息
|
|
95
|
+
>
|
|
96
|
+
> │ │ └─ [id]/ —— 动态参数路由示例
|
|
97
|
+
>
|
|
98
|
+
> │ │ └─ [name].vue —— 路由 /home/:id/:name
|
|
99
|
+
>
|
|
100
|
+
> │ ├─ App.vue —— 根组件
|
|
101
|
+
>
|
|
102
|
+
> │ ├─ main.js / main.ts —— 项目启动入口
|
|
103
|
+
>
|
|
104
|
+
> │ └─ style.css —— 全局样式文件
|
|
105
|
+
>
|
|
106
|
+
> ├─ index.html —— 项目入口页面
|
|
107
|
+
>
|
|
108
|
+
> ├─ jsconfig.json / tsconfig.json —— 路径别名与编译配置
|
|
109
|
+
>
|
|
110
|
+
> ├─ package.json —— 项目依赖与脚本配置
|
|
111
|
+
>
|
|
112
|
+
> ├─ postcss.config.mjs —— Tailwind CSS 配置文件(可选)
|
|
113
|
+
>
|
|
114
|
+
> ├─ README.md —— 项目说明文档
|
|
115
|
+
>
|
|
116
|
+
> └─ vite.config.ts —— Vite 开发与构建配置
|
|
101
117
|
|
|
102
118
|
---
|
|
103
119
|
|
|
104
|
-
## ⚙️
|
|
120
|
+
## ⚙️ 使用方式(多包管理器支持)
|
|
105
121
|
|
|
106
122
|
1. 创建项目
|
|
123
|
+
|
|
107
124
|
```bash
|
|
108
125
|
npm create vite-vue@latest
|
|
126
|
+
pnpm create vite-vue@latest
|
|
109
127
|
```
|
|
110
128
|
|
|
111
129
|
2. 进入项目目录
|
|
130
|
+
|
|
112
131
|
```bash
|
|
113
132
|
cd 项目名
|
|
114
133
|
```
|
|
115
134
|
|
|
116
|
-
3. 安装依赖
|
|
135
|
+
3. 安装依赖
|
|
136
|
+
|
|
117
137
|
```bash
|
|
118
138
|
npm install
|
|
139
|
+
pnpm install
|
|
119
140
|
```
|
|
120
141
|
|
|
121
142
|
4. 启动开发环境
|
|
143
|
+
|
|
122
144
|
```bash
|
|
123
145
|
npm run dev
|
|
146
|
+
pnpm dev
|
|
124
147
|
```
|
|
125
148
|
|
|
126
|
-
> 如果在创建时选择了「立即运行」,工具会自动执行启动命令。
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## 🌐 技术栈官网链接
|
|
131
|
-
|
|
132
|
-
- [Vite](https://vitejs.dev/)
|
|
133
|
-
- [Vue 3](https://vuejs.org/)
|
|
134
|
-
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
135
|
-
- [TypeScript](https://www.typescriptlang.org/)
|
|
136
|
-
- [Vue Router](https://router.vuejs.org/)
|
|
137
|
-
- [Pinia](https://pinia.vuejs.org/)
|
|
138
|
-
- [Axios](https://axios-http.com/)
|
|
139
|
-
- [Element Plus](https://element-plus.org/)
|
|
140
|
-
- [Vant](https://vant-contrib.gitee.io/vant/)
|
|
141
|
-
- [VueUse](https://vueuse.org/)
|
|
142
|
-
- [Lodash](https://lodash.com/)
|
|
143
|
-
- [Day.js](https://day.js.org/)
|
|
144
|
-
- [Tailwind CSS](https://tailwindcss.com/)
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## 🟢 Node.js 版本管理(.nvmrc)
|
|
149
|
-
|
|
150
|
-
项目根目录中包含一个 **`.nvmrc`** 文件,用于指定当前项目推荐使用的**Node.js 版本**。这样可以保证不同开发者或不同机器运行项目时使用一致的 Node环境,避免依赖问题。
|
|
151
|
-
|
|
152
|
-
### 使用 nvm 切换 Node 版本
|
|
153
|
-
|
|
154
|
-
如果你安装了 **nvm(Node Version Manager)**,进入项目目录后执行:
|
|
155
|
-
|
|
156
|
-
``` bash
|
|
157
|
-
nvm use
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
nvm 会自动读取 `.nvmrc` 文件中的 Node 版本并切换。
|
|
161
|
-
|
|
162
|
-
### Windows 可能出现的问题
|
|
163
|
-
|
|
164
|
-
在 **Windows PowerShell** 中,`nvm use` 有时不会自动读取`.nvmrc`,可能会报错或无法切换版本。
|
|
165
|
-
|
|
166
|
-
如果出现这种情况,可以执行:
|
|
167
|
-
|
|
168
|
-
``` powershell
|
|
169
|
-
nvm use $(Get-Content .nvmrc)
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
该命令会读取 `.nvmrc` 文件内容并手动切换 Node 版本。
|
|
173
|
-
|
|
174
149
|
---
|
|
175
150
|
|
|
176
151
|
## 🔧 常见需要调整的地方(具体文件示例)
|
|
177
152
|
|
|
178
153
|
### 1️⃣ 接口请求地址
|
|
179
154
|
|
|
180
|
-
文件:`src/utils/request.ts`
|
|
155
|
+
文件:`src/utils/request.ts` / `src/utils/request.js`
|
|
156
|
+
|
|
181
157
|
```ts
|
|
182
158
|
import axios from 'axios';
|
|
183
159
|
|
|
@@ -187,7 +163,7 @@ const service = axios.create({
|
|
|
187
163
|
});
|
|
188
164
|
|
|
189
165
|
// 示例请求
|
|
190
|
-
export const getUserList = () =>
|
|
166
|
+
export const getUserList = () => service.get('/users');
|
|
191
167
|
|
|
192
168
|
export default service;
|
|
193
169
|
```
|
|
@@ -198,7 +174,8 @@ export default service;
|
|
|
198
174
|
|
|
199
175
|
### 2️⃣ 本地代理配置
|
|
200
176
|
|
|
201
|
-
文件:`vite.config.ts`
|
|
177
|
+
文件:`vite.config.ts` / `vite.config.js`
|
|
178
|
+
|
|
202
179
|
```ts
|
|
203
180
|
import { defineConfig } from 'vite';
|
|
204
181
|
import vue from '@vitejs/plugin-vue';
|
|
@@ -224,7 +201,8 @@ export default defineConfig({
|
|
|
224
201
|
|
|
225
202
|
### 3️⃣ 路由结构(支持动态参数)
|
|
226
203
|
|
|
227
|
-
文件:`src/router/index.ts`
|
|
204
|
+
文件:`src/router/index.ts` / `src/router/index.js`
|
|
205
|
+
|
|
228
206
|
```ts
|
|
229
207
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
230
208
|
import routes from '~pages' // 自动生成的路由
|
|
@@ -237,14 +215,16 @@ const router = createRouter({
|
|
|
237
215
|
export default router
|
|
238
216
|
```
|
|
239
217
|
|
|
240
|
-
>
|
|
218
|
+
> 页面文件夹结构示例:
|
|
219
|
+
|
|
241
220
|
```text
|
|
242
221
|
src/views/home/
|
|
243
222
|
├─ index.vue -> /home
|
|
244
223
|
└─ [id]/[name].vue -> /home/:id/:name
|
|
245
224
|
```
|
|
246
225
|
|
|
247
|
-
>
|
|
226
|
+
> 获取路由参数:
|
|
227
|
+
|
|
248
228
|
```ts
|
|
249
229
|
import { useRoute } from 'vue-router'
|
|
250
230
|
const route = useRoute()
|
|
@@ -257,6 +237,7 @@ console.log(route.params.name)
|
|
|
257
237
|
### 4️⃣ 页面内容与样式
|
|
258
238
|
|
|
259
239
|
文件示例:`src/views/home/index.vue`
|
|
240
|
+
|
|
260
241
|
```vue
|
|
261
242
|
<template>
|
|
262
243
|
<div class="home-container">
|
|
@@ -281,6 +262,64 @@ console.log(route.params.name)
|
|
|
281
262
|
|
|
282
263
|
---
|
|
283
264
|
|
|
265
|
+
### 5️⃣ Mitt 事件总线使用示例
|
|
266
|
+
|
|
267
|
+
#### 封装事件总线
|
|
268
|
+
|
|
269
|
+
文件:`src/utils/eventBus.ts`
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import mitt from 'mitt'
|
|
273
|
+
|
|
274
|
+
type Events = {
|
|
275
|
+
userLogin: { name: string },
|
|
276
|
+
userLogout: null
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const emitter = mitt<Events>()
|
|
280
|
+
|
|
281
|
+
export default emitter
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### 使用示例
|
|
285
|
+
|
|
286
|
+
##### 组件 A(发送事件)
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
<script setup lang="ts">
|
|
290
|
+
import eventBus from '@/utils/eventBus'
|
|
291
|
+
|
|
292
|
+
function login() {
|
|
293
|
+
eventBus.emit('userLogin', { name: '张三' })
|
|
294
|
+
}
|
|
295
|
+
</script>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
##### 组件 B(接收事件)
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
<script setup lang="ts">
|
|
302
|
+
import { onMounted, onUnmounted } from 'vue'
|
|
303
|
+
import eventBus from '@/utils/eventBus'
|
|
304
|
+
|
|
305
|
+
function handleLogin(payload: { name: string }) {
|
|
306
|
+
console.log('用户登录:', payload.name)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
onMounted(() => {
|
|
310
|
+
eventBus.on('userLogin', handleLogin)
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
onUnmounted(() => {
|
|
314
|
+
eventBus.off('userLogin', handleLogin)
|
|
315
|
+
})
|
|
316
|
+
</script>
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
> 🔹 Mitt 事件总线轻量高效,适合组件间解耦通信,替代父子传递 props / emit 或 Vuex/Pinia 中的小型事件场景。
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
284
323
|
## 🎯 适用场景
|
|
285
324
|
|
|
286
325
|
- Vue 3 新手快速上手
|
|
@@ -291,6 +330,25 @@ console.log(route.params.name)
|
|
|
291
330
|
|
|
292
331
|
---
|
|
293
332
|
|
|
333
|
+
## 🌐 技术栈官网链接
|
|
334
|
+
|
|
335
|
+
- [Vite | 下一代的前端工具链](https://cn.vitejs.dev/)
|
|
336
|
+
- [Vue.js - 渐进式 JavaScript 框架 | Vue.js](https://cn.vuejs.org/)
|
|
337
|
+
- [JavaScript](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
|
|
338
|
+
- [TypeScript](https://www.typescriptlang.org/)
|
|
339
|
+
- [Vue Router | Vue.js 的官方路由](https://router.vuejs.org/zh/)
|
|
340
|
+
- [Pinia | The intuitive store for Vue.js](https://pinia.vuejs.org/zh/)
|
|
341
|
+
- [Axios](https://www.axios-http.cn/)
|
|
342
|
+
- [Element Plus | 一个 Vue 3 UI 框架](https://element-plus.org/zh-CN/)
|
|
343
|
+
- [Vant 4 - 轻量、可定制的移动端组件库](https://vant-ui.github.io/vant/#/zh-CN)
|
|
344
|
+
- [VueUse](https://vueuse.pages.dev/)
|
|
345
|
+
- [Lodash](https://www.lodashjs.com/)
|
|
346
|
+
- [Day.js](https://day.js.org/)
|
|
347
|
+
- [Tailwind CSS](https://tailwindcss.com/)
|
|
348
|
+
- [Mitt](https://github.com/developit/mitt)
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
294
352
|
## 📄 License
|
|
295
353
|
|
|
296
354
|
MIT License
|
|
@@ -11,17 +11,14 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"less": "^4.5.1",
|
|
13
13
|
"tslib": "^2.8.1",
|
|
14
|
-
"vue": "^3.5.
|
|
14
|
+
"vue": "^3.5.30"__OPTIONAL_DEP__
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@types/node": "^24.
|
|
18
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
19
|
-
"@vue/tsconfig": "^0.
|
|
17
|
+
"@types/node": "^24.12.0",
|
|
18
|
+
"@vitejs/plugin-vue": "^6.0.5",
|
|
19
|
+
"@vue/tsconfig": "^0.9.0",
|
|
20
20
|
"typescript": "~5.9.3",
|
|
21
|
-
"vite": "^8.0.
|
|
22
|
-
"vue-tsc": "^3.
|
|
23
|
-
},
|
|
24
|
-
"overrides": {
|
|
25
|
-
"vite": "^8.0.0-beta.13"
|
|
21
|
+
"vite": "^8.0.1",
|
|
22
|
+
"vue-tsc": "^3.2.5"
|
|
26
23
|
}
|
|
27
24
|
}
|