create-vite-vue 1.0.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.
Files changed (35) hide show
  1. package/bin/index.js +211 -0
  2. package/package.json +27 -0
  3. package/template/axios-js/src/api/index.js +0 -0
  4. package/template/axios-js/src/utils/request.js +18 -0
  5. package/template/axios-ts/src/api/index.ts +0 -0
  6. package/template/axios-ts/src/utils/request.ts +18 -0
  7. package/template/base-js/README.md +32 -0
  8. package/template/base-js/index.html +13 -0
  9. package/template/base-js/jsconfig.json +15 -0
  10. package/template/base-js/package.json.tpl +23 -0
  11. package/template/base-js/public/vite.svg +1 -0
  12. package/template/base-js/src/App.vue +64 -0
  13. package/template/base-js/src/assets/vue.svg +1 -0
  14. package/template/base-js/src/main.js.tpl +16 -0
  15. package/template/base-js/src/style.css +39 -0
  16. package/template/base-js/vite.config.js +25 -0
  17. package/template/base-ts/README.md +32 -0
  18. package/template/base-ts/index.html +13 -0
  19. package/template/base-ts/package.json.tpl +27 -0
  20. package/template/base-ts/public/vite.svg +1 -0
  21. package/template/base-ts/src/App.vue +64 -0
  22. package/template/base-ts/src/assets/vue.svg +1 -0
  23. package/template/base-ts/src/main.ts.tpl +16 -0
  24. package/template/base-ts/src/style.css +39 -0
  25. package/template/base-ts/src/vite-env.d.ts +6 -0
  26. package/template/base-ts/tsconfig.app.json +16 -0
  27. package/template/base-ts/tsconfig.json +22 -0
  28. package/template/base-ts/tsconfig.node.json +26 -0
  29. package/template/base-ts/vite.config.ts +25 -0
  30. package/template/pinia-js/src/stores/index.js +0 -0
  31. package/template/pinia-ts/src/stores/index.ts +0 -0
  32. package/template/router-js/src/router/index.js +13 -0
  33. package/template/router-js/src/views/Home.vue +64 -0
  34. package/template/router-ts/src/router/index.ts +13 -0
  35. package/template/router-ts/src/views/Home.vue +64 -0
package/bin/index.js ADDED
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env node
2
+ import { execSync } from 'child_process'
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+ import prompts from 'prompts'
6
+ import { fileURLToPath } from 'url'
7
+
8
+ const __filename = fileURLToPath(import.meta.url)
9
+ const __dirname = path.dirname(__filename)
10
+
11
+ async function createProject () {
12
+ // 1️⃣ 输入项目名
13
+ let projectName
14
+ while (true) {
15
+ const res = await prompts({
16
+ type: 'text',
17
+ name: 'projectName',
18
+ message: '📦 项目名称',
19
+ validate: v => v ? true : '项目名不能为空'
20
+ })
21
+ projectName = res.projectName
22
+ if (!projectName) process.exit(1)
23
+
24
+ const targetDir = path.resolve(process.cwd(), projectName)
25
+ if (fs.existsSync(targetDir)) {
26
+ console.log('❌ 目录已存在,请重新输入')
27
+ continue
28
+ }
29
+ break
30
+ }
31
+
32
+ const targetDir = path.resolve(process.cwd(), projectName)
33
+
34
+ const { language } = await prompts({
35
+ type: 'select',
36
+ name: 'language',
37
+ message: '请选择项目语言',
38
+ choices: [
39
+ { title: 'JavaScript', value: 'js' },
40
+ { title: 'TypeScript', value: 'ts' }
41
+ ]
42
+ })
43
+
44
+
45
+ // 2️⃣ 功能选择
46
+ const features = await prompts([
47
+ {
48
+ type: 'select',
49
+ name: 'router',
50
+ message: '是否使用 vue-router?',
51
+ choices: [{ title: 'Yes', value: true }, { title: 'No', value: false }]
52
+ },
53
+ {
54
+ type: 'select',
55
+ name: 'pinia',
56
+ message: '是否使用 Pinia(含持久化)?',
57
+ choices: [{ title: 'Yes', value: true }, { title: 'No', value: false }]
58
+ },
59
+ {
60
+ type: 'select',
61
+ name: 'axios',
62
+ message: '是否使用 Axios?',
63
+ choices: [{ title: 'Yes', value: true }, { title: 'No', value: false }]
64
+ },
65
+ {
66
+ type: 'select',
67
+ name: 'ui',
68
+ message: '请选择 UI 框架',
69
+ choices: [
70
+ { title: 'Element Plus(PC)', value: 'element' },
71
+ { title: 'Vant(Mobile)', value: 'vant' },
72
+ { title: '不使用 UI 框架', value: 'none' }
73
+ ]
74
+ }
75
+ ])
76
+
77
+ // 3️⃣ 是否立即运行 dev
78
+ const { runDev } = await prompts({
79
+ type: 'select',
80
+ name: 'runDev',
81
+ message: '是否立即运行 npm run dev?',
82
+ choices: [{ title: 'Yes', value: true }, { title: 'No', value: false }]
83
+ })
84
+
85
+ // 4️⃣ 拷贝 base 模板
86
+ const baseTemplate = language === 'ts' ? 'base-ts' : 'base-js'
87
+ fs.cpSync(
88
+ path.resolve(__dirname, `../template/${baseTemplate}`),
89
+ targetDir,
90
+ { recursive: true }
91
+ )
92
+
93
+ // 4️⃣-1️⃣ 替换 index.html 的 title
94
+ const indexPath = path.join(targetDir, 'index.html')
95
+ if (fs.existsSync(indexPath)) {
96
+ const indexContent = fs.readFileSync(indexPath, 'utf-8')
97
+ fs.writeFileSync(
98
+ indexPath,
99
+ indexContent.replace(/<title>.*<\/title>/, `<title>${projectName}</title>`)
100
+ )
101
+ }
102
+
103
+ // 5️⃣ 拷贝可选模板
104
+ const copy = name => {
105
+ fs.cpSync(path.resolve(__dirname, `../template/${name}`), targetDir, { recursive: true })
106
+ }
107
+ features.router && copy(language === 'ts' ? 'router-ts' : 'router-js')
108
+ features.pinia && copy(language === 'ts' ? 'pinia-ts' : 'pinia-js')
109
+ features.axios && copy(language === 'ts' ? 'axios-ts' : 'axios-js')
110
+
111
+ // 6️⃣ 生成 main.js
112
+ const mainFile = language === 'ts' ? 'main.ts' : 'main.js'
113
+ const mainTplPath = path.join(targetDir, `src/${mainFile}.tpl`)
114
+ let main = fs.readFileSync(mainTplPath, 'utf-8')
115
+
116
+ const replacements = {
117
+ '/* __ROUTER_IMPORT__ */': features.router ? "import router from './router'" : '',
118
+ '/* __PINIA_IMPORT__ */': features.pinia
119
+ ? "import { createPinia } from 'pinia'\nimport persistedstate from 'pinia-plugin-persistedstate'"
120
+ : '',
121
+ '/* __ELEMENT_IMPORT__ */': features.ui === 'element'
122
+ ? `import ElementPlus from 'element-plus'
123
+ import 'element-plus/dist/index.css'
124
+ import * as ElementPlusIconsVue from '@element-plus/icons-vue'`
125
+ : '',
126
+ '/* __VANT_IMPORT__ */': features.ui === 'vant'
127
+ ? `import Vant from 'vant'
128
+ import 'vant/lib/index.css'`
129
+ : '',
130
+ '/* __ROUTER_USE__ */': features.router ? 'app.use(router)' : '',
131
+ '/* __PINIA_USE__ */': features.pinia
132
+ ? 'app.use(createPinia().use(persistedstate))'
133
+ : '',
134
+ '/* __ELEMENT_USE__ */': features.ui === 'element'
135
+ ? `app.use(ElementPlus)
136
+ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
137
+ app.component(key, component)
138
+ }`
139
+ : '',
140
+ '/* __VANT_USE__ */': features.ui === 'vant'
141
+ ? 'app.use(Vant)'
142
+ : ''
143
+ }
144
+
145
+ function escapeRegExp (str) {
146
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
147
+ }
148
+
149
+ for (const [placeholder, content] of Object.entries(replacements)) {
150
+ if (content) {
151
+ main = main.replace(placeholder, content)
152
+ } else {
153
+ const re = new RegExp(`^\\s*${escapeRegExp(placeholder)}\\s*$\\n?`, 'gm')
154
+ main = main.replace(re, '')
155
+ }
156
+ }
157
+
158
+ fs.writeFileSync(
159
+ path.join(targetDir, `src/${mainFile}`),
160
+ main
161
+ )
162
+ fs.unlinkSync(mainTplPath)
163
+
164
+ // 7️⃣ 生成 package.json
165
+ const pkgTpl = path.join(targetDir, 'package.json.tpl')
166
+ if (fs.existsSync(pkgTpl)) {
167
+ let pkg = fs.readFileSync(pkgTpl, 'utf-8')
168
+
169
+ const optionalDeps = {}
170
+ if (features.router) optionalDeps['vue-router'] = '^4.4.0'
171
+ if (features.pinia) {
172
+ optionalDeps['pinia'] = '^2.2.2'
173
+ optionalDeps['pinia-plugin-persistedstate'] = '^3.2.1'
174
+ }
175
+ if (features.axios) optionalDeps['axios'] = '^1.7.7'
176
+ if (features.ui === 'element') {
177
+ optionalDeps['element-plus'] = '^2.8.8'
178
+ optionalDeps['@element-plus/icons-vue'] = '^2.3.1'
179
+ }
180
+ if (features.ui === 'vant') {
181
+ optionalDeps['vant'] = '^4.9.22'
182
+ }
183
+
184
+ let depsStr = ''
185
+ const keys = Object.keys(optionalDeps)
186
+ if (keys.length > 0) {
187
+ depsStr = ',\n' + keys.map(k => ` "${k}": "${optionalDeps[k]}"`).join(',\n')
188
+ }
189
+
190
+ pkg = pkg
191
+ .replace('__PROJECT_NAME__', projectName)
192
+ .replace('__OPTIONAL_DEP__', depsStr)
193
+
194
+ fs.writeFileSync(path.join(targetDir, 'package.json'), pkg)
195
+ fs.unlinkSync(pkgTpl)
196
+ }
197
+
198
+ // 8️⃣ 安装依赖
199
+ console.log('📦 安装依赖中...')
200
+ execSync('npm install', { cwd: targetDir, stdio: 'inherit' })
201
+
202
+ // 9️⃣ 运行 dev
203
+ if (runDev) {
204
+ console.log('🚀 启动开发服务器...')
205
+ execSync('npm run dev', { cwd: targetDir, stdio: 'inherit' })
206
+ } else {
207
+ console.log(`\n✅ 项目创建完成\n👉 cd ${projectName}\n👉 npm run dev\n`)
208
+ }
209
+ }
210
+
211
+ createProject()
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "create-vite-vue",
3
+ "version": "1.0.0",
4
+ "description": "基于Vite+Vue3创建基础项目模板",
5
+ "main": "index.js",
6
+ "author": "YwaiX",
7
+ "license": "MIT",
8
+ "type": "module",
9
+ "bin": {
10
+ "create-vite-vue": "bin/index.js"
11
+ },
12
+ "scripts": {
13
+ "test": "echo \"Error: no test specified\" && exit 1"
14
+ },
15
+ "keywords": [
16
+ "vite",
17
+ "vue",
18
+ "js",
19
+ "ts",
20
+ "vue-router",
21
+ "pinia",
22
+ "axios"
23
+ ],
24
+ "dependencies": {
25
+ "prompts": "^2.4.2"
26
+ }
27
+ }
File without changes
@@ -0,0 +1,18 @@
1
+ import axios from 'axios'
2
+
3
+ const service = axios.create({
4
+ baseURL: '/api',
5
+ timeout: 10000
6
+ })
7
+
8
+ service.interceptors.request.use(
9
+ config => config,
10
+ error => Promise.reject(error)
11
+ )
12
+
13
+ service.interceptors.response.use(
14
+ response => response.data,
15
+ error => Promise.reject(error)
16
+ )
17
+
18
+ export default service
File without changes
@@ -0,0 +1,18 @@
1
+ import axios from 'axios'
2
+
3
+ const service = axios.create({
4
+ baseURL: '/api',
5
+ timeout: 10000
6
+ })
7
+
8
+ service.interceptors.request.use(
9
+ config => config,
10
+ error => Promise.reject(error)
11
+ )
12
+
13
+ service.interceptors.response.use(
14
+ response => response.data,
15
+ error => Promise.reject(error)
16
+ )
17
+
18
+ export default service
@@ -0,0 +1,32 @@
1
+ # Vite + Vue3 + js + vue-router + pinia + element-plus + axios + less
2
+
3
+ 本项目基于Vite + Vue3 + js + vue-router + pinia + element-plus + axios + less创建
4
+
5
+
6
+
7
+ 运行方式
8
+
9
+ ```text
10
+ cd my-project
11
+ npm i
12
+ npm run dev
13
+ ```
14
+
15
+
16
+
17
+ 需要修改的地方
18
+
19
+ ```text
20
+ utils/request.js
21
+ router/index.js
22
+ ```
23
+
24
+
25
+
26
+ 可以修改的地方
27
+
28
+ ```text
29
+ vite.config.js
30
+ ```
31
+
32
+ 该文件中的`server.proxy`,`server.host`,`server.port`可以进行更改,其他地方不建议更改
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="zh">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>vue-template-js</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.js"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,15 @@
1
+ // jsconfig.json
2
+ {
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "paths": {
6
+ "@/*": [
7
+ "src/*"
8
+ ]
9
+ }
10
+ },
11
+ "exclude": [
12
+ "node_modules",
13
+ "dist"
14
+ ]
15
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "__PROJECT_NAME__",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "less": "^4.5.1",
13
+ "tslib": "^2.8.1",
14
+ "vue": "^3.5.24"__OPTIONAL_DEP__
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^6.0.1",
18
+ "vite": "npm:rolldown-vite@7.2.5"
19
+ },
20
+ "overrides": {
21
+ "vite": "npm:rolldown-vite@7.2.5"
22
+ }
23
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="welcome-container">
3
+ <div class="welcome-card">
4
+ <h1 class="welcome-title">欢迎来到我的项目!</h1>
5
+ <p class="welcome-desc">
6
+ 这是一个 Vue 3 + JS 版基础项目的欢迎页面示例。
7
+ </p>
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup>
13
+
14
+
15
+ </script>
16
+
17
+ <style scoped>
18
+ /* 外层容器,全屏居中 */
19
+ .welcome-container {
20
+ width: 100vw;
21
+ height: 100vh;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ background: linear-gradient(135deg, #4facfe, #00f2fe);
26
+ }
27
+
28
+ /* 卡片样式 */
29
+ .welcome-card {
30
+ background-color: rgba(255, 255, 255, 0.9);
31
+ padding: 40px;
32
+ border-radius: 16px;
33
+ text-align: center;
34
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
35
+ animation: fadeIn 1s ease;
36
+ }
37
+
38
+ /* 标题 */
39
+ .welcome-title {
40
+ font-size: 2.5rem;
41
+ margin-bottom: 20px;
42
+ color: #333;
43
+ }
44
+
45
+ /* 描述 */
46
+ .welcome-desc {
47
+ font-size: 1.2rem;
48
+ margin-bottom: 30px;
49
+ color: #555;
50
+ }
51
+
52
+ /* 标题淡入动画 */
53
+ @keyframes fadeIn {
54
+ from {
55
+ opacity: 0;
56
+ transform: translateY(-20px);
57
+ }
58
+
59
+ to {
60
+ opacity: 1;
61
+ transform: translateY(0);
62
+ }
63
+ }
64
+ </style>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
@@ -0,0 +1,16 @@
1
+ import { createApp } from 'vue'
2
+ import App from './App.vue'
3
+ import './style.css'
4
+ /* __ELEMENT_IMPORT__ */
5
+ /* __ROUTER_IMPORT__ */
6
+ /* __PINIA_IMPORT__ */
7
+ /* __VANT_IMPORT__ */
8
+
9
+ const app = createApp(App)
10
+
11
+ /* __ELEMENT_USE__ */
12
+ /* __ROUTER_USE__ */
13
+ /* __PINIA_USE__ */
14
+ /* __VANT_USE__ */
15
+
16
+ app.mount('#app')
@@ -0,0 +1,39 @@
1
+ body {
2
+ margin: 0;
3
+ padding: 0;
4
+ }
5
+
6
+ .el-header,
7
+ .el-footer {
8
+ background-color: #B3C0D1;
9
+ color: #333;
10
+ text-align: center;
11
+ line-height: 60px;
12
+ }
13
+
14
+ .el-aside {
15
+ background-color: #D3DCE6;
16
+ color: #333;
17
+ text-align: center;
18
+ line-height: 200px;
19
+ }
20
+
21
+ .el-main {
22
+ background-color: #E9EEF3;
23
+ color: #333;
24
+ text-align: center;
25
+ line-height: 160px;
26
+ }
27
+
28
+ body>.el-container {
29
+ margin-bottom: 40px;
30
+ }
31
+
32
+ .el-container:nth-child(5) .el-aside,
33
+ .el-container:nth-child(6) .el-aside {
34
+ line-height: 260px;
35
+ }
36
+
37
+ .el-container:nth-child(7) .el-aside {
38
+ line-height: 320px;
39
+ }
@@ -0,0 +1,25 @@
1
+ import vue from '@vitejs/plugin-vue'
2
+ import path from 'path'
3
+ import { defineConfig } from 'vite'
4
+
5
+ // https://vite.dev/config/
6
+ export default defineConfig({
7
+ plugins: [vue()],
8
+ resolve: {
9
+ alias: {
10
+ '@': path.resolve(__dirname, './src')
11
+ }
12
+ },
13
+ server: {
14
+ host: '0.0.0.0',
15
+ port: 20000,
16
+ strictPort: false,
17
+ proxy: {
18
+ '/api': {
19
+ target: 'http://localhost:8080',
20
+ changeOrigin: true,
21
+ rewrite: path => path.replace(/^\/api/, '')
22
+ }
23
+ }
24
+ }
25
+ })
@@ -0,0 +1,32 @@
1
+ # Vite + Vue3 + ts + vue-router + pinia + element-plus + axios + less
2
+
3
+ 本项目基于Vite + Vue3 + ts + vue-router + pinia + element-plus + axios + less创建
4
+
5
+
6
+
7
+ 运行方式
8
+
9
+ ```text
10
+ cd my-project
11
+ npm i
12
+ npm run dev
13
+ ```
14
+
15
+
16
+
17
+ 需要修改的地方
18
+
19
+ ```text
20
+ utils/request.ts
21
+ router/index.ts
22
+ ```
23
+
24
+
25
+
26
+ 可以修改的地方
27
+
28
+ ```text
29
+ vite.config.ts
30
+ ```
31
+
32
+ 该文件中的`server.proxy`,`server.host`,`server.port`可以进行更改,其他地方不建议更改
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>vue-template-ts</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "__PROJECT_NAME__",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vue-tsc -b && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "less": "^4.5.1",
13
+ "tslib": "^2.8.1",
14
+ "vue": "^3.5.24"__OPTIONAL_DEP__
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^24.10.4",
18
+ "@vitejs/plugin-vue": "^6.0.1",
19
+ "@vue/tsconfig": "^0.8.1",
20
+ "typescript": "~5.9.3",
21
+ "vite": "npm:rolldown-vite@7.2.5",
22
+ "vue-tsc": "^3.1.4"
23
+ },
24
+ "overrides": {
25
+ "vite": "npm:rolldown-vite@7.2.5"
26
+ }
27
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="welcome-container">
3
+ <div class="welcome-card">
4
+ <h1 class="welcome-title">欢迎来到我的项目!</h1>
5
+ <p class="welcome-desc">
6
+ 这是一个 Vue 3 + TS 版基础项目的欢迎页面示例。
7
+ </p>
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+
14
+
15
+ </script>
16
+
17
+ <style scoped>
18
+ /* 外层容器,全屏居中 */
19
+ .welcome-container {
20
+ width: 100vw;
21
+ height: 100vh;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ background: linear-gradient(135deg, #4facfe, #00f2fe);
26
+ }
27
+
28
+ /* 卡片样式 */
29
+ .welcome-card {
30
+ background-color: rgba(255, 255, 255, 0.9);
31
+ padding: 40px;
32
+ border-radius: 16px;
33
+ text-align: center;
34
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
35
+ animation: fadeIn 1s ease;
36
+ }
37
+
38
+ /* 标题 */
39
+ .welcome-title {
40
+ font-size: 2.5rem;
41
+ margin-bottom: 20px;
42
+ color: #333;
43
+ }
44
+
45
+ /* 描述 */
46
+ .welcome-desc {
47
+ font-size: 1.2rem;
48
+ margin-bottom: 30px;
49
+ color: #555;
50
+ }
51
+
52
+ /* 标题淡入动画 */
53
+ @keyframes fadeIn {
54
+ from {
55
+ opacity: 0;
56
+ transform: translateY(-20px);
57
+ }
58
+
59
+ to {
60
+ opacity: 1;
61
+ transform: translateY(0);
62
+ }
63
+ }
64
+ </style>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
@@ -0,0 +1,16 @@
1
+ import { createApp } from 'vue'
2
+ import App from './App.vue'
3
+ import './style.css'
4
+ /* __ELEMENT_IMPORT__ */
5
+ /* __ROUTER_IMPORT__ */
6
+ /* __PINIA_IMPORT__ */
7
+ /* __VANT_IMPORT__ */
8
+
9
+ const app = createApp(App)
10
+
11
+ /* __ELEMENT_USE__ */
12
+ /* __ROUTER_USE__ */
13
+ /* __PINIA_USE__ */
14
+ /* __VANT_USE__ */
15
+
16
+ app.mount('#app')
@@ -0,0 +1,39 @@
1
+ body {
2
+ margin: 0;
3
+ padding: 0;
4
+ }
5
+
6
+ .el-header,
7
+ .el-footer {
8
+ background-color: #B3C0D1;
9
+ color: #333;
10
+ text-align: center;
11
+ line-height: 60px;
12
+ }
13
+
14
+ .el-aside {
15
+ background-color: #D3DCE6;
16
+ color: #333;
17
+ text-align: center;
18
+ line-height: 200px;
19
+ }
20
+
21
+ .el-main {
22
+ background-color: #E9EEF3;
23
+ color: #333;
24
+ text-align: center;
25
+ line-height: 160px;
26
+ }
27
+
28
+ body>.el-container {
29
+ margin-bottom: 40px;
30
+ }
31
+
32
+ .el-container:nth-child(5) .el-aside,
33
+ .el-container:nth-child(6) .el-aside {
34
+ line-height: 260px;
35
+ }
36
+
37
+ .el-container:nth-child(7) .el-aside {
38
+ line-height: 320px;
39
+ }
@@ -0,0 +1,6 @@
1
+ /// <reference types="vite/client" />
2
+ declare module '*.vue' {
3
+ import type { DefineComponent } from 'vue'
4
+ const vueComponent: DefineComponent<{}, {}, any>
5
+ export default vueComponent
6
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
3
+ "compilerOptions": {
4
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
5
+ "types": ["vite/client"],
6
+
7
+ /* Linting */
8
+ "strict": true,
9
+ "noUnusedLocals": true,
10
+ "noUnusedParameters": true,
11
+ "erasableSyntaxOnly": true,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "noUncheckedSideEffectImports": true
14
+ },
15
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
16
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": "./",
4
+ "paths": {
5
+ "@/*": [
6
+ "./src/*"
7
+ ]
8
+ },
9
+ "module": "esnext",
10
+ "target": "esnext",
11
+ "moduleResolution": "node",
12
+ },
13
+ "include": [
14
+ "src/**/*.ts",
15
+ "src/**/*.tsx",
16
+ "src/**/*.vue",
17
+ "tests/**/*.ts",
18
+ "tests/**/*.tsx",
19
+ "typings",
20
+ "src/.env"
21
+ ]
22
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2023",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "types": ["node"],
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "verbatimModuleSyntax": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "erasableSyntaxOnly": true,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noUncheckedSideEffectImports": true
24
+ },
25
+ "include": ["vite.config.ts"]
26
+ }
@@ -0,0 +1,25 @@
1
+ import vue from '@vitejs/plugin-vue'
2
+ import path from 'path'
3
+ import { defineConfig } from 'vite'
4
+
5
+ // https://vite.dev/config/
6
+ export default defineConfig({
7
+ plugins: [vue()],
8
+ resolve: {
9
+ alias: {
10
+ '@': path.resolve(__dirname, './src')
11
+ }
12
+ },
13
+ server: {
14
+ host: '0.0.0.0',
15
+ port: 20000,
16
+ strictPort: false,
17
+ proxy: {
18
+ '/api': {
19
+ target: 'http://localhost:8080',
20
+ changeOrigin: true,
21
+ rewrite: (path) => path.replace(/^\/api/, '')
22
+ }
23
+ }
24
+ }
25
+ })
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ import { createRouter, createWebHistory } from 'vue-router'
2
+
3
+ const routes = [
4
+ {
5
+ path: '/',
6
+ component: () => import('@/views/Home.vue')
7
+ }
8
+ ]
9
+
10
+ export default createRouter({
11
+ history: createWebHistory(),
12
+ routes
13
+ })
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="welcome-container">
3
+ <div class="welcome-card">
4
+ <h1 class="welcome-title">欢迎来到我的项目!</h1>
5
+ <p class="welcome-desc">
6
+ 这是一个 Vue 3 + JS 版基础项目的欢迎页面示例。
7
+ </p>
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup>
13
+
14
+
15
+ </script>
16
+
17
+ <style scoped>
18
+ /* 外层容器,全屏居中 */
19
+ .welcome-container {
20
+ width: 100vw;
21
+ height: 100vh;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ background: linear-gradient(135deg, #4facfe, #00f2fe);
26
+ }
27
+
28
+ /* 卡片样式 */
29
+ .welcome-card {
30
+ background-color: rgba(255, 255, 255, 0.9);
31
+ padding: 40px;
32
+ border-radius: 16px;
33
+ text-align: center;
34
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
35
+ animation: fadeIn 1s ease;
36
+ }
37
+
38
+ /* 标题 */
39
+ .welcome-title {
40
+ font-size: 2.5rem;
41
+ margin-bottom: 20px;
42
+ color: #333;
43
+ }
44
+
45
+ /* 描述 */
46
+ .welcome-desc {
47
+ font-size: 1.2rem;
48
+ margin-bottom: 30px;
49
+ color: #555;
50
+ }
51
+
52
+ /* 标题淡入动画 */
53
+ @keyframes fadeIn {
54
+ from {
55
+ opacity: 0;
56
+ transform: translateY(-20px);
57
+ }
58
+
59
+ to {
60
+ opacity: 1;
61
+ transform: translateY(0);
62
+ }
63
+ }
64
+ </style>
@@ -0,0 +1,13 @@
1
+ import { createRouter, createWebHistory } from 'vue-router'
2
+
3
+ const routes = [
4
+ {
5
+ path: '/',
6
+ component: () => import('@/views/Home.vue')
7
+ }
8
+ ]
9
+
10
+ export default createRouter({
11
+ history: createWebHistory(),
12
+ routes
13
+ })
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="welcome-container">
3
+ <div class="welcome-card">
4
+ <h1 class="welcome-title">欢迎来到我的项目!</h1>
5
+ <p class="welcome-desc">
6
+ 这是一个 Vue 3 + TS 版基础项目的欢迎页面示例。
7
+ </p>
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+
14
+
15
+ </script>
16
+
17
+ <style scoped>
18
+ /* 外层容器,全屏居中 */
19
+ .welcome-container {
20
+ width: 100vw;
21
+ height: 100vh;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ background: linear-gradient(135deg, #4facfe, #00f2fe);
26
+ }
27
+
28
+ /* 卡片样式 */
29
+ .welcome-card {
30
+ background-color: rgba(255, 255, 255, 0.9);
31
+ padding: 40px;
32
+ border-radius: 16px;
33
+ text-align: center;
34
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
35
+ animation: fadeIn 1s ease;
36
+ }
37
+
38
+ /* 标题 */
39
+ .welcome-title {
40
+ font-size: 2.5rem;
41
+ margin-bottom: 20px;
42
+ color: #333;
43
+ }
44
+
45
+ /* 描述 */
46
+ .welcome-desc {
47
+ font-size: 1.2rem;
48
+ margin-bottom: 30px;
49
+ color: #555;
50
+ }
51
+
52
+ /* 标题淡入动画 */
53
+ @keyframes fadeIn {
54
+ from {
55
+ opacity: 0;
56
+ transform: translateY(-20px);
57
+ }
58
+
59
+ to {
60
+ opacity: 1;
61
+ transform: translateY(0);
62
+ }
63
+ }
64
+ </style>