简介这是一份面向Vue.js初学者与前端进阶者的实战练习资源围绕一个简易资产管理应用展开帮助读者在动手编码中理解框架的核心用法。资源包共39个文件以15个js脚本、9个.vue单文件组件为主辅以7张png界面截图、2个json配置及html、md等说明文件压缩包约45KB体量轻巧便于快速上手。内容覆盖Vue实例与数据绑定、计算属性与侦听器、组件化拆分、模板语法中的条件与循环渲染并延伸至Vue Router路由管理、Vuex状态管理、响应式布局与错误处理等知识点目录中可见components、router、build、config等模块划分结构清晰。目前已有4211人学习下载适合希望通过完整小项目串联零散语法、积累组件化与工程化经验的开发者参考借鉴。1. 从一份能跑起来的 Vue 小例子说起很多前端新手卡在“看完文档还是不会写”这一步不是语法没记住而是缺一个能直接跑、能改、能看到反馈的完整小项目。这份 Vue 前端小例子就是干这个的它把组件拆分、数据绑定、事件处理、列表渲染、条件渲染这些日常开发里绕不开的东西塞进一个体量可控的工程里让你 clone 下来npm install就能在浏览器里看到效果。它适合刚学完 Vue 基础语法、想找个练手项目巩固的人也适合需要快速搭一个演示原型、不想从零配脚手架的开发者。下面我按“能干什么 → 怎么跑 → 怎么改”的顺序把这个小例子拆开讲一遍。2. 项目定位与技术选型为什么是 Vue 而不是别的2.1 这个例子解决的是什么问题前端学习最怕两件事一是例子太碎每个知识点单独看都懂合起来就不会组织二是例子太重还没开始学就被 webpack 配置、路由守卫、状态管理劝退。这份 Vue 前端小例子走的是中间路线——它不追求功能大而全而是把 Vue 最核心的响应式数据流讲清楚。你打开页面能看到一个列表、几个按钮、一个输入框点一下按钮列表变了输入框里打字页面上同步显示这就是 Vue 的看家本领数据驱动视图。它不依赖后端接口所有数据写在前端 mock 里所以你不用起数据库、不用配跨域打开就能玩。从技术选型上看它用的是 Vue 2 或 Vue 3 的单文件组件写法具体版本以你拿到的源码为准配合 Vue CLI 或 Vite 作为构建工具。为什么不用原生 HTML 加 script 标签引入因为单文件组件把 template、script、style 写在一个.vue文件里更接近真实项目结构你以后进公司看到的代码基本长这样。常见做法是小例子用 Vite 起项目因为冷启动快、配置少如果源码里是 Vue CLI那也没关系命令换成npm run serve而已。2.2 目录结构长什么样拿到源码先别急着跑花两分钟看目录后面改代码心里有底。一个典型的 Vue 小例子目录大概是这样vue-demo/ ├── public/ │ └── index.html # 页面模板一般不动 ├── src/ │ ├── assets/ # 静态图片、样式 │ ├── components/ # 可复用组件 │ │ ├── ItemList.vue # 列表组件 │ │ └── AddItem.vue # 添加表单项 │ ├── App.vue # 根组件页面入口 │ └── main.js # 应用初始化挂载 Vue 实例 ├── package.json # 依赖和脚本命令 └── vite.config.js # 构建配置Vue CLI 则是 vue.config.jsmain.js是黑匣子的入口它把根组件挂到index.html的#app节点上。App.vue负责组织页面布局把子组件拼起来。components/里的组件各管一块比如ItemList.vue只负责渲染列表AddItem.vue只负责输入和提交。这种拆分方式就是 Vue 组件化的基本思路一个组件只做一件事数据通过 props 往下传事件通过 emit 往上报。2.3 核心依赖和脚本命令打开package.json你会看到dependencies里有vuedevDependencies里有vite或vue/cli-service。脚本命令通常就三个{ scripts: { dev: vite, build: vite build, preview: vite preview } }dev是开发模式带热更新改代码浏览器自动刷新build是打包生产版本输出到dist/preview是本地预览打包结果。如果你拿到的是 Vue CLI 项目命令对应serve、build、lint。这里有个血泪经验别在dev模式下测性能开发模式没压缩、没 Tree-shaking打包后的体积和速度才是真实水平。3. 跑起来从安装依赖到浏览器看到页面3.1 环境准备和安装步骤先确认你机器上有 Node.js版本建议 16 以上。命令行敲node -v和npm -v能看到版本号就行。然后进项目根目录执行# 安装依赖国内网络慢可以换淘宝源 npm install # 启动开发服务器 npm run dev如果npm install卡住不动大概率是网络问题可以临时用npm install --registryhttps://registry.npmmirror.com。装完之后node_modules文件夹会很大这是正常的别手动去改里面的东西。启动成功后终端会打印一个本地地址通常是http://localhost:5173或http://localhost:8080复制到浏览器打开就能看到页面。注意如果端口被占用Vite 会自动换一个端口看终端输出为准别死磕默认端口。3.2 页面上的交互是怎么串起来的页面打开后你看到的是一个列表和几个操作按钮。以“添加条目”为例整个数据流是这样的用户在AddItem.vue的输入框里打字输入框绑定了一个v-model数据实时同步到组件的data或ref里点提交按钮触发一个方法方法里把新数据 push 到列表数组因为列表数组是响应式的Vue 检测到变化后自动重新渲染ItemList.vue页面上就多了一行。整个过程你不需要手动操作 DOM这就是 Vue 的核心卖点。常见做法是在父组件App.vue里维护列表数据通过 props 传给ItemList.vue渲染同时把添加方法通过事件传给AddItem.vue调用。这样数据只有一个源头改起来不容易乱。如果你看到源码里数据分散在各个子组件那说明它用的是另一种组织方式也能跑但后期维护会麻烦一点。3.3 构建和部署到静态服务器开发调试没问题后执行npm run build项目会打包到dist/目录。这个目录里就是纯静态的 HTML、CSS、JS 文件扔到任何静态服务器上都能跑。本地想验证打包结果用npm run preview起一个本地服务看效果。注意打包后路径问题如果部署到子目录需要在vite.config.js里配base否则资源 404。这个坑我踩过好几次页面白屏控制台一堆 404最后发现是base没写对。4. 核心模块拆解组件、数据流和事件处理4.1 根组件 App.vue 的组织方式App.vue是整个页面的骨架它通常长这样template div classapp h1Vue 小例子/h1 !-- 添加组件监听自定义事件 -- AddItem addhandleAdd / !-- 列表组件把数据传下去 -- ItemList :itemsitems removehandleRemove / /div /template script import AddItem from ./components/AddItem.vue import ItemList from ./components/ItemList.vue export default { components: { AddItem, ItemList }, data() { return { items: [ { id: 1, text: 第一条数据 }, { id: 2, text: 第二条数据 } ] } }, methods: { handleAdd(text) { // 生成简单唯一 id实际项目用 uuid this.items.push({ id: Date.now(), text }) }, handleRemove(id) { this.items this.items.filter(item item.id ! id) } } } /script这里items是唯一数据源handleAdd和handleRemove都只改这个数组。AddItem通过add把用户输入抛上来ItemList通过:items拿到数据渲染通过remove把删除意图抛上来。这种“数据往下传、事件往上报”的模式是 Vue 组件通信的基础你把这个例子吃透后面学 Vuex 或 Pinia 会顺很多。4.2 列表组件 ItemList.vue 的渲染逻辑ItemList.vue负责把数组渲染成列表核心是v-for和:keytemplate ul classitem-list li v-foritem in items :keyitem.id span{{ item.text }}/span button click$emit(remove, item.id)删除/button /li /ul /template script export default { props: { items: { type: Array, required: true } } } /scriptv-for遍历items每一项渲染一个li。:key必须写且必须唯一通常用后端返回的 id。如果你用 index 当 key在列表中间插入或删除时会出现渲染错位这是 Vue 里最经典的坑之一。$emit(remove, item.id)把删除事件和 id 一起抛给父组件父组件收到后过滤数组。注意 props 是只读的子组件不能直接改items只能通过事件让父组件改这是单向数据流的规矩。4.3 添加组件 AddItem.vue 的双向绑定AddItem.vue演示了v-model和表单处理template div classadd-item input v-modelinputValue placeholder输入内容 keyup.entersubmit / button clicksubmit添加/button /div /template script export default { data() { return { inputValue: } }, methods: { submit() { const text this.inputValue.trim() if (!text) return this.$emit(add, text) this.inputValue // 清空输入框 } } } /scriptv-model是:value加input的语法糖输入框内容变化时inputValue自动更新。keyup.enter让回车也能提交提升体验。提交前trim()去空格并判空防止添加空条目。提交后清空输入框方便连续添加。这些细节看着小但真实项目里少一个判空就可能被测试提 bug。5. 避坑与常见问题新手跑这个例子最容易翻车的几个点5.1 页面白屏控制台报错现象npm run dev启动成功浏览器打开一片白控制台红字。原因通常是路由模式不对或资源路径错误。如果项目用了 history 模式路由开发服务器需要配 fallback如果是打包后部署到子目录base没配。解决开发阶段先看控制台第一条报错定位是哪个文件加载失败打包部署时在vite.config.js里设base: ./或具体子路径。5.2 修改数据页面不更新现象在方法里改了数组或对象但页面没反应。原因Vue 2 对数组下标赋值和对象新增属性不是响应式的Vue 3 用 Proxy 没这个问题但如果你直接替换了整个引用也可能出问题。解决Vue 2 里用this.$set或数组的push/splice方法Vue 3 里确保你改的是响应式对象别把ref的值整个覆盖成普通对象。5.3 npm install 报错 node 版本不兼容现象安装依赖时一堆gyp错误或engine警告。原因项目依赖要求的 Node 版本和你本机不一致。解决用nvm或n切换 Node 版本看package.json里的engines字段没有的话试 16 或 18 这两个长期支持版。别用太新的奇数版本容易遇到依赖没适配。5.4 端口被占用起不来现象npm run dev报EADDRINUSE。原因上一个开发服务器没关干净或者别的程序占了端口。解决Mac/Linux 用lsof -i :5173找到进程 kill 掉Windows 用netstat -ano | findstr 5173找 PID 再 taskkill。或者直接在配置里改端口Vite 是server.portVue CLI 是devServer.port。5.5 打包后图片和字体加载失败现象本地开发正常打包部署后图片裂了、字体不生效。原因CSS 里引用的相对路径在打包后变了或者public目录和assets目录用法搞混。解决小图片放src/assets让构建工具处理大文件或需要保持原名的放public用绝对路径引用。CSS 里用url()引资源时注意相对路径基准。6. 二次开发把这个小例子改成你自己的练手项目6.1 从列表增删改成待办事项这个例子最自然的改造方向就是待办事项Todo List。你只需要在现有基础上加两个东西完成状态和过滤。给每个 item 加一个done布尔字段列表项渲染时根据done加删除线样式点击文字切换状态。再加一个过滤栏用计算属性根据当前过滤条件返回不同的数组computed: { filteredItems() { if (this.filter active) { return this.items.filter(item !item.done) } if (this.filter done) { return this.items.filter(item item.done) } return this.items } }模板里把v-foritem in items改成v-foritem in filteredItems过滤切换只改filter的值列表自动更新。计算属性有缓存比在模板里写方法效率高这是 Vue 的另一个核心知识点改完这个你就把计算属性也练了。6.2 加本地存储让数据刷新不丢现在刷新页面数据就回到初始状态加个localStorage就能持久化。在App.vue里用watch监听items变化变化时写入本地组件创建时从本地读created() { const saved localStorage.getItem(vue-demo-items) if (saved) { this.items JSON.parse(saved) } }, watch: { items: { deep: true, handler(newVal) { localStorage.setItem(vue-demo-items, JSON.stringify(newVal)) } } }deep: true让 Vue 监听数组内部元素的变化不然 push 操作可能触发不了。注意JSON.parse要加 try-catch防止本地存了脏数据导致页面崩。这个改造做完你就掌握了 Vue 的侦听器和生命周期钩子比单纯看文档印象深得多。6.3 拆成路由页面练 Vue Router如果想把例子升级成多页面应用引入vue-router把列表页和关于页拆成两个路由组件。在main.js里app.use(router)配置路由表App.vue里放router-view。这样你就能练到路由传参、编程式导航、路由守卫这些真实项目必备技能。改造时注意路由组件和普通组件写法一样只是通过路由匹配决定渲染哪个。别一上来就上 Vuex先把路由玩明白状态管理等数据跨页面共享时再引入也不迟。6.4 一个我常犯的错误我刚开始改这类例子时总喜欢在子组件里直接改 props觉得方便结果控制台警告不说数据流一乱后面加功能就崩。从那以后我每次拆组件都强制自己走一遍“数据在父、事件往上抛”的流程哪怕多写几行代码。这个习惯让我后面学 Pinia 时几乎没遇到理解障碍因为状态管理的本质也是把共享数据抽到统一的地方管。希望这个例子你也能跑一遍、改一遍比看十篇教程都管用。本文还有配套的精品资源点击获取