第一章:开篇暴击——为什么你的项目结构总像一团毛线?
记得我刚学Vue那会儿,每次用Vue CLI创建项目后,看着自动生成的文件树,内心OS都是:“这都啥跟啥啊?src文件夹里为啥还要分assets和components?router和store是干嘛的?难道不能把所有代码都堆在App.vue里吗?”
结果第二天,我的项目就变成了“意大利面条式代码”——数据流动像迷宫,组件耦合得像连体婴,每次改功能都像在拆炸弹。直到被项目经理追杀了三条街后,我才顿悟:精通项目结构不是装逼,是保命啊!
如今Vue生态里杀出Vite这匹黑马,很多小伙伴又开始纠结:“我是坚守Vue CLI这个老司机,还是投奔Vite这个小鲜肉?” 别急,今天咱们就用打群架的架势,把这两位的项目结构扒个底朝天!
(突然正经)先上核心结论:Vue CLI像装修齐全的精装房,开箱即用;Vite像毛坯房+万能施工队,按需定制。接下来咱们直接进入“大家来找茬”模式。
第二章:Vue CLI项目结构——老司机的标准操作手册
先用Vue CLI创建一个项目压压惊(假设你已安装,没装的快去面壁):
vue create my-old-school-project
生成的文件树长这样:
my-old-school-project
├── node_modules/ # 懂的都懂,薛定谔的文件夹——时大时小,永远不敢删
├── public/
│ ├── favicon.ico
│ └── index.html # 入口HTML,江湖人称“门面担当”
├── src/
│ ├── assets/ # 静态资源仓库,图片字体往里扔就对了
│ ├── components/ # 组件收容所,但容易变成“垃圾抽屉”
│ ├── router/ # 路由指挥部,定义谁在哪站上车下车
│ ├── store/ # Vuex数据银行,存取款都得按规矩来
│ ├── views/ # 页面级组件公寓,和components的区别…问就是玄学
│ ├── App.vue # 组件宇宙的中心,所有组件的终极妈妈
│ └── main.js # 程序启动按钮,一按全厂通电
├── .gitignore # 告诉Git哪些黑历史不必追踪
├── babel.config.js # JS翻译官,让旧浏览器听懂新时代语法
├── package.json # 项目身份证+技能清单,没有它npm直接罢工
└── vue.config.js # 隐藏关卡配置,解锁后能为所欲为
重点文件精讲:
- package.json——项目的“技能树”:
{
"scripts": {
"serve": "vue-cli-service serve", // 启动开发服务器
"build": "vue-cli-service build", // 打包生产版本
"lint": "vue-cli-service lint" // 代码体检,专治不规范
},
"dependencies": {
"vue": "^2.6.14", // 核心大佬,没它全剧终
"vue-router": "^3.5.1", // 路由管家
"vuex": "^3.6.2" // 状态大管家
}
}
- vue.config.js——隐藏的威力增幅器:
module.exports = {
devServer: {
port: 8080, // 改端口,解决“端口被占”的祖传问题
proxy: {
'/api': 'http://localhost:3000' // 代理解决跨域,前端撩后端必备
}
},
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].title = "我的骚气项目" // 自定义HTML标题
return args
})
}
}
- src/main.js——程序启动的“红色按钮”:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false // 关闭生产提示,别问,问就是嫌它吵
new Vue({
router, // 注入路由系统
store, // 注入状态管理
render: h => h(App) // 渲染根组件
}).$mount('#app') // 挂载到index.html的app元素
Vue CLI的优势总结:配置封装完善,生态插件丰富,适合需要“稳如老狗”的企业级项目。但代价是node_modules体积感人(动不动几百MB),冷启动速度像春运火车。
第三章:Vite项目结构——闪电侠的极速哲学
是时候请出新时代网红Vite了!创建项目:
npm create vite@latest my-new-school-project -- --template vue
生成的文件树乍看和Vue CLI差不多,但内核天差地别:
my-new-school-project
├── node_modules/ # 体积减半,感动哭
├── public/ # 静态资源老岗位
├── src/
│ ├── assets/
│ ├── components/
│ └── App.vue
├── index.html # 重点!升级为C位大佬,直接放项目根目录
├── package.json
├── vite.config.js # 新配置文件,语法更风骚
└── env.d.ts # TypeScript类型声明,贴心小棉袄
核心差异点解剖:
- index.html翻身做主人:
在Vite中,index.html从public文件夹搬到了项目根目录,而且可以直接引用ES模块:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script> <!-- 直接ES模块导入 -->
</body>
</html>
- vite.config.js——配置界的极简主义:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 为什么用defineConfig?为了自动提示!真香!
export default defineConfig({
plugins: [vue()], // 插件数组,按需插拔
server: {
port: 3000, // 开发服务器端口
open: true // 自动打开浏览器,懒人福音
},
build: {
outDir: 'dist' // 打包输出目录
}
})
- main.js——ES模块原生玩家:
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
// 没有全局Vue实例,每个应用独立创建
createApp(App).mount('#app')
Vite的杀手锏:基于ES模块的无打包开发环境,冷启动秒开,HMR(热更新)速度甩Webpack几条街。尤其适合:1)需要快速原型的项目;2)对开发体验有极致追求的同学;3)被Webpack编译速度折磨到秃头的难民。
第四章:实战PK——用两个工具创建同一个TODO应用
光说不练假把式,咱们用两个工具分别创建同一个TODO应用,对比开发体验。
公共组件代码(两个项目通用):
<!-- TodoItem.vue -->
<template>
<li :class="{ completed: todo.completed }">
<input
type="checkbox"
:checked="todo.completed"
@change="$emit('toggle', todo.id)"
>
<span>{{ todo.text }}</span>
<button @click="$emit('delete', todo.id)">删除</button>
</li>
</template>
<script>
export default {
props: ['todo'],
emits: ['toggle', 'delete']
}
</script>
<style scoped>
.completed {
text-decoration: line-through;
color: #888;
}
</style>
<!-- App.vue -->
<template>
<div id="app">
<h1>我的摸鱼待办清单</h1>
<form @submit.prevent="addTodo">
<input v-model="newTodo" placeholder="写下你要摸的鱼...">
<button type="submit">添加</button>
</form>
<ul>
<TodoItem
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@toggle="toggleTodo"
@delete="deleteTodo"
/>
</ul>
</div>
</template>
<script>
import { ref, computed } from 'vue'
import TodoItem from './components/TodoItem.vue'
export default {
components: { TodoItem },
setup() {
const newTodo = ref('')
const todos = ref([])
let nextId = 1
const addTodo = () => {
if (newTodo.value.trim()) {
todos.value.push({
id: nextId++,
text: newTodo.value,
completed: false
})
newTodo.value = ''
}
}
const toggleTodo = (id) => {
const todo = todos.value.find(t => t.id === id)
if (todo) todo.completed = !todo.completed
}
const deleteTodo = (id) => {
todos.value = todos.value.filter(t => t.id !== id)
}
return {
newTodo, todos, addTodo, toggleTodo, deleteTodo
}
}
}
</script>
开发体验对比:
- Vue CLI:运行
npm run serve后等待10-30秒(取决于电脑配置),看到“Compiled successfully”松一口气。 - Vite:运行
npm run dev后1-2秒浏览器自动打开,修改代码几乎实时响应。
打包对比:
- Vue CLI:
npm run build生成优化后的文件,包含vendor chunk、app chunk等 - Vite:
npm run build输出更细粒度的代码分割,默认支持ES模块格式
第五章:选择困难症急救指南——我该Pick谁?
看完实战,估计有同学选择困难症又犯了。别急,收下这份急救指南:
无脑选Vue CLI的情况:
- 公司传统项目迁移,求稳不求快
- 需要兼容IE11等老古董浏览器(Vite默认不支持)
- 项目依赖大量Webpack特定插件/配置
- 你是配置恐惧症患者,希望开箱即用
闭眼选Vite的情况:
- 新项目启动,尤其Vue 3项目
- 开发效率至上,拒绝等待编译
- 项目以现代浏览器为主战场
- 你喜欢折腾新工具,拥抱前沿
彩蛋:其实两者可以共存!老项目用Vue CLI维护,新模块用Vite开发,通过微前端整合。进阶玩法,这里就不展开了(主要是写不动了)。
结语
从Vue CLI到Vite,就像从功能机到智能机——刚开始可能不习惯,但一旦用上就回不去了。无论选择哪个工具,理解项目结构都是成为Vue高手的必经之路。毕竟,只会写单文件组件,就像只会开自动挡——能开走,但修不了车。
现在,是时候打开你的终端,亲手创建两个项目感受一下了!如果过程中遇到坑,别慌——那说明你正在上坡路上。

被折叠的 条评论
为什么被折叠?



