ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vue3组件化开发实战:从脚手架搭建到工程落地

Vue3组件化开发实战:从脚手架搭建到工程落地 1. 组件化编程的认知重构与脚手架的价值先说点实在的。很多人学Vue前一周还在看模板语法、指令、计算属性一到组件化这三个字就懵了——组件到底是什么为什么要拆拆到什么程度算合理说白了组件化就是把页面当成乐高积木来拼每一块积木负责自己的样子和行为积木和积木之间通过规定的接口互相协作。你不再写一个三千行的巨型页面而是写十几个各司其职的小模块每个模块又能单独测试、单独复用、单独维护这就是组件化的核心价值。那脚手架又是干什么的如果你是手动从零搭Vue项目光配置webpack/vite、Babel、ESLint、开发服务器就得折腾一两天而且配置错了还不好排查。脚手架的本质就是把这一整套工程化的基础设施给你预装好你拿到手就是一个能直接跑、能直接写代码的干净项目。Vue官方现在主推的create-vue脚手架底层是基于Vite的冷启动速度快到离谱热更新也是毫秒级开发体验比老一代的webpack方案舒服太多。这篇文章适合什么人看刚学完Vue基础语法、准备进入组件化开发阶段的新手或者已经在用Vue但一直会写不会讲、想把自己的组件化思路理顺的开发者。我会从最核心的组件设计思路开始讲再带你完整过一遍Vue脚手架的创建、目录结构、路由配置以及实际开发中一定会踩的坑。学完你至少能独立搭建一个结构清晰、可维护性达标的Vue3工程。2. 组件拆分的核心逻辑与设计思路2.1 为什么要拆组件维护成本的现实账我先算一笔账。假设一个后台管理页面有表格、搜索表单、分页、弹窗、详情抽屉这五块内容你全部写在一个文件里初期可能三四百行还能撑住。但业务一旦开始迭代——表格加几列、搜索条件加两个下拉、弹窗再加个嵌套表单——这个文件会迅速膨胀到上千行。到那个时候你改一个表格列配置都要在密密麻麻的代码里翻半天git冲突概率直线上升新同事接手更是无从下手。拆成组件之后情况完全不同。搜索表单是独立的SearchForm.vue表格是DataTable.vue弹窗是DetailDialog.vue每个文件最多一两百行职责单一谁负责哪块一目了然。改表格逻辑不会影响到搜索区测试哪个组件就单独跑哪个组件配合Vite的热更新基本做到改哪看哪。我自己的经验是判断一个模块要不要拆成组件主要看三个信号是否在多个页面重复出现、单个文件是否超过300行、内部是否有相对独立的业务闭环。三个条件满足任意两个就值得拆。不要为了追求文件数量而硬拆一个只有一句话的模板没必要单独成一个组件过度拆分反而增加组件间的通信成本。2.2 组件分类容器组件与展示组件在真实项目中我习惯把组件分成两类容器组件也叫聪明组件和展示组件也叫哑组件。这个区分非常实用能直接决定你的组件是否容易被复用。容器组件负责业务逻辑——发请求、处理数据、维护状态它知道数据从哪来、要干什么。展示组件只负责长得好看——接收props把数据渲染出来用户做了什么操作就通过事件向外抛自己不存业务数据。举个例子一个用户列表页面UserList.vue是容器组件负责调用接口、管理userList数组、处理加载状态UserTable.vue是展示组件只接收userList这个prop把表格渲染出来点击编辑按钮时emit(edit, row)通知父组件。这样设计的直接好处是以后换一套后端接口只需要改容器组件表格的展示逻辑一行不用动如果另一个页面也要展示相似表格直接把UserTable.vue拿过去复用就行。这个思路用一句大白话讲让组件各司其职别让一个组件既当爹又当妈。2.3 组件通信方案选型按场景用量级决定组件拆好了接下来最关键的问题就是通信。Vue3的通信方式比Vue2更丰富选择多了反而容易踩坑。我第一次从Vue2转Vue3时习惯性地想用事件总线结果发现Vue3移除了$on/$off事件总线的生态一下子变得尴尬。好在Vue3官方推荐了更清晰的路子。先看一张我平时做技术选型时参考的对照表通信场景推荐方案适用量级父传子props任意层级单向数据流子传父emit 自定义事件直接父子关系兄弟/跨层级provide/inject深层嵌套中等量级任意组件Pinia / Vuex全局状态跨页面共享复杂表单跨组件v-model defineModel表单类组件封装props和emit是组件通信的基础这个必须吃透。父组件通过:user-listuserList往下传子组件用defineProps声明接收修改数据只能通过emit(update:user-list, newVal)通知父组件改这就是单向数据流——数据流向清晰调试的时候顺着方向查就行。跨层级的场景比如根组件给三层以下的孙组件传一个主题色用provide/inject最合适。父组件provide(themeColor, themeColor)中间任何层级的组件都能用inject(themeColor)直接拿到不用一层层props转发。这里要注意provide的值默认不是响应式的如果你想动态更新需要传一个ref对象或者使用computed这个细节我第一次用的时候踩了坑排查了半天为什么主题色不跟着变。至于全局状态我的建议是项目里有多个页面共享用户登录信息、购物车数据、权限标识这类状态时直接上Pinia。不要为了少装一个库而硬用props跨十几个层级传递那会让代码维护变得极其痛苦。3. 从零用Vue脚手架搭建工程3.1 环境准备Node.js 版本与 npm 镜像动手创建项目之前先把环境弄利索。Vue3 Vite 这条技术栈对 Node.js 版本有硬性要求Vite 5 需要 Node 18Vite 6 需要 Node 18.17 或 20。如果你还在用 Node 14/16创建项目的时候会直接报错提示版本不满足要求。所以第一步先检查你的Node版本node -v npm -v如果版本偏低去Node官网下载最新的LTS版本装上就行。这里我给个实操建议装Node的时候顺手把nvmNode Version Manager也装上它是Node的版本管理器以后项目多了经常需要在不同Node版本之间切换nvm一条命令就能搞定省去反复卸载安装的麻烦。然后是npm镜像的问题。国内直接跑npm install经常慢到让人怀疑人生甚至直接卡死。解决办法是配置淘宝镜像源国内开发者应该都懂npm config set registry https://registry.npmmirror.com配置完之后可以用npm config get registry确认是否生效。这一步做得好后面安装依赖能节省大量时间。3.2 create-vue 创建项目与交互式选项解读环境没问题了就可以用官方脚手架create-vue创建项目。直接跑npm create vuelatest这个命令会自动拉取最新版的create-vue然后在终端里出现一系列交互式提问类似于一个项目功能选配向导。以下是常见的选项和我的选择建议提示选项推荐选择说明Project nameyour-project-name项目名只能用英文建议小写加连字符Add TypeScript?按团队需求新手可先选No熟悉后再迁移Add JSX Support?No默认组件写法用不到JSXAdd Vue Router?Yes前端路由必用后面会详细讲Add Pinia?Yes状态管理建议直接装上Add Vitest?看项目需求写单元测试才需要Add ESLint and Prettier?Yes保证代码规范强烈建议从第一天就启用选完之后脚手架会自动生成一个完整的项目然后按照终端的提示依次执行cd your-project-name npm install npm run dev几秒钟后终端会输出一个本地访问地址一般是http://localhost:5173浏览器打开就能看到Vue官方的欢迎页面这说明你的脚手架已经跑起来了。我提一个很多新手会忽略的点npm create vuelatest里的latest不是装饰它明确指定拉取最新版本避免npm缓存里有过期的旧版本。如果你之前跑过老版本建议加上latest强制拉新不然可能创建出Vite 2时代的老项目。3.3 项目结构逐层拆解与职责说明脚手架生成的目录结构看起来很复杂其实拆开看非常清晰。我逐个讲解每个目录和文件的用途这是理解工程化的第一课。your-project-name/ ├── node_modules/ # 项目依赖包目录npm install 生成的 ├── public/ # 公共资源目录不会被构建工具处理 │ └── favicon.ico # 浏览器标签页图标 ├── src/ # 源码目录开发的主战场 │ ├── assets/ # 静态资源图片、样式等会被构建工具处理 │ ├── components/ # 公共组件目录 │ ├── router/ # 路由配置目录 │ │ └── index.js # 路由实例与路由表 │ ├── stores/ # Pinia 状态管理目录 │ │ └── counter.js # 示例状态下 │ ├── views/ # 页面级组件目录 │ │ └── HomeView.vue │ ├── App.vue # 应用根组件所有组件树的根 │ └── main.js # 应用入口文件创建应用实例并挂载 ├── index.html # Vite 的入口 HTML 文件 ├── package.json # 项目依赖、脚本命令、配置信息 ├── vite.config.js # Vite 构建配置 └── README.md # 项目说明文档main.js是最核心的启动文件里面做的事可以理解为组装应用并启动。脚手架默认生成的main.js大致长这样import { createApp } from vue import App from ./App.vue import router from ./router import { createPinia } from pinia const app createApp(App) app.use(createPinia()) app.use(router) app.mount(#app)逻辑很直白用createApp创建应用实例注册Pinia和路由插件最后调用mount(#app)把整个应用挂载到index.html里div idapp/div这个节点上。以后你想全局注册一个组件、引入一个UI库都是在main.js里通过app.use()或app.component()来做。3.4 第一个组件单文件组件的三角结构脚手架的工程跑起来了现在亲手写一个组件。Vue单文件组件SFC由三个部分组成template写结构、script setup写逻辑、style写样式。三块内容放在同一个.vue文件里作用域互相配合这也是Vue组件化的基础形态。我写一个简单的卡片组件作为示例template div classuser-card h3{{ user.name }}/h3 p{{ user.title }}/p button clickhandleFollow关注/button /div /template script setup import { ref } from vue const props defineProps({ user: { type: Object, required: true } }) const isFollowed ref(false) const handleFollow () { isFollowed.value !isFollowed.value } /script style scoped .user-card { border: 1px solid #ddd; border-radius: 8px; padding: 16px; } /style注意style scoped里的scoped关键字它表示这个样式只对当前组件生效。Vue会在编译时给当前组件的所有元素加一个>!-- Card.vue -- div classcard header slot nameheader默认标题/slot /header main slot默认内容/slot /main footer slot namefooter / /footer /div父组件里用template标签配合v-slot指令来填充Card template #header用户信息/template p这里是卡片主体内容/p template #footer button确认/button button取消/button /template /Card#header是v-slot:header的简写形式Vue3推荐的语法。还有一类是作用域插槽用来解决子组件的数据想交给父组件的插槽来渲染这个需求。比如列表组件内部已经拿到了数据但每一行的展示方式想交给父组件决定!-- DataList.vue -- ul li v-foritem in items :keyitem.id slot :itemitem :indexindex / /li /ul父组件使用DataList :itemslist template #default{ item } span{{ item.name }}/span em{{ item.price }}/em /template /DataList插槽的熟练运用是组件从基本能用升级到灵活可扩展的关键台阶。我见过很多项目里组件写死模板结果换个页面的展示需求就要复制一份组件代码这就是没用好插槽的代价。4.2 动态组件与keep-alive页面切换的性能优化在后台管理系统中经常遇到根据当前菜单动态切换页面内容的需求。Vue的component :iscurrentComponent /动态组件就是为这种场景设计的它根据变量值动态渲染对应的组件。动态组件配合keep-alive是一对经典搭档。keep-alive的作用是缓存组件实例切换走的时候不销毁组件切回来直接恢复不需要重新渲染和重新请求数据。这在带有搜索条件、滚动位置、表单单据等场景的页面中尤其有用。但要注意缓存是有代价的——被缓存的组件写在onActivated和onDeactivated声明周期里的代码会影响切换行为。我自己的经验是列表页需要缓存切回来要保持搜索条件和滚动位置表单页不要缓存切回来要重新加载最新数据否则会出现提交过的数据还残留的问题。具体用法keep-alive component :iscurrentView / /keep-alive还可以通过include/exclude属性精确控制缓存哪些组件比如只缓存列表页面keep-alive :include[UserList, OrderList] router-view / /keep-alive4.3 自定义指令按钮权限控制的优雅解法热词里提到vue按钮权限怎么控制这是企业级项目里绕不开的需求。登录用户的角色不一样界面上能看到的按钮也不一样——普通员工看不到删除管理员能看到。很多人第一反应是每个按钮加一个v-if判断但这样判断逻辑散落在各个组件里后期维护成本很高。更优雅的方案是自定义指令。我用得最顺手的是v-permission指令它把权限校验的逻辑集中在指令定义处模板里只要写一行button v-permissionuser:delete删除/button指令的定义实现// src/directives/permission.js import { useAuthStore } from /stores/auth export const permission { mounted(el, binding) { const { value } binding const authStore useAuthStore() // 从状态管理中获取当前用户拥有的权限码数组 const enabled authStore.permissions.includes(value) // 没有权限直接移除DOM元素 if (!enabled) { el.parentNode el.parentNode.removeChild(el) } } }然后在main.js里全局注册import { permission } from ./directives/permission app.directive(permission, permission)为什么用自定义指令而不是v-if因为指令把权限的校验和渲染逻辑彻底封装了模板简洁、复用性高、权限码变更时只需要维护状态管理的权限数组和接口返回的权限数据不用满项目搜v-if。这是工程化思维的一个典型体现。4.4 组件库按需引入打包体积控制的必修课几乎每一个Vue实战项目都会引入组件库Element Plus、Ant Design Vue、Naive UI是最常见的几个。它们的共同特点是组件特别多全量引入会导致打包体积非常夸张。Element Plus全量引入仅仅JS部分就接近1MB对页面加载速度是很大的负担。按需引入是解决方案。以Element Plus为例官方推荐的方案是配合unplugin-auto-import和unplugin-vue-components这两个插件自动按需引入组件和API// vite.config.js import AutoImport from unplugin-auto-import/vite import Components from unplugin-vue-components/vite import { ElementPlusResolver } from unplugin-vue-components/resolvers export default defineConfig({ plugins: [ AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], })配置好之后模板里直接用el-button、el-table插件会在编译阶段自动把用到的组件和对应样式引入没用到的一点都不会进打包产物。实测下来一个管理后台的打包体积能从1MB多降到400KB左右首屏加载时间能快将近一半。这里有个坑要提醒unplugin-vue-components是自动导入组件但函数式的API比如ElMessage、ElMessageBox需要额外的样式手动引入。我用Element Plus时吃了这个亏弹窗样式全是乱的排查了半天才意识到是没手动引样式import element-plus/es/components/message/style/css import element-plus/es/components/message-box/style/css5. Vue Router 路由体系与实践5.1 路由基础router与route的职责区分Vue Router是单页应用SPA的核心基础设施。单页应用只有一个HTML页面之所以能在不同页面之间切换全靠前端路由用JavaScript控制URL变化并渲染对应的组件。很多新手搞不清router和route的区别。简单说router是路由器负责跳转router.push、router.replaceroute是当前路由信息只读描述当前地址对应的各种信息路径、参数、query等。可以这样类比router是导航仪告诉你现在要去哪route是当前所在位置的路牌告诉你现在在哪。脚手架默认生成的路由配置大概是这样的结构// src/router/index.js import { createRouter, createWebHistory } from vue-router import HomeView from /views/HomeView.vue const router createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: /, name: home, component: HomeView }, { path: /about, name: about, component: () import(/views/AboutView.vue) } ] }) export default router注意AboutView.vue使用的是动态导入() import(...)写法这叫路由懒加载。它会在用户访问/about时才加载这个组件的代码而不是应用启动时就把所有页面代码都下载下来。后台管理系统页面一多路由懒加载对首屏性能的影响非常大这几行代码一定不能省。5.2 动态路由与权限路由的落地动态路由是热词里高频出现的关键词也是后台管理系统最常见的路由需求不同角色登录后看到的菜单不一样。实现思路并不复杂核心就是先登录再根据权限信息动态添加路由。第一步定义只属于特定角色的路由权限路由比如只有管理员能访问的用户管理页、系统设置页。第二步用户登录后接口返回该用户的角色和权限码数组前端根据权限码生成该用户应该能访问的路由表。第三步用router.addRoute()方法动态添加这些路由再用router.getRoutes()确认添加成功。// 根据权限码过滤出允许访问的路由 function generateRoutes(permissions) { const allRoutes [ { path: /user-management, name: UserManagement, component: () import(/views/UserManagement.vue), meta: { permissions: [admin] } } // ...其他权限路由 ] return allRoutes.filter(route route.meta.permissions.some(p permissions.includes(p)) ) } // 登录成功后动态添加 const allowedRoutes generateRoutes(userInfo.permissions) allowedRoutes.forEach(route { router.addRoute(route) })同时配合前置守卫做跳转拦截router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (!token to.path ! /login) { next(/login) } else { next() } })一个完整的权限路由需要后端配合返回用户可访问的菜单和权限前端做动态路由和守卫拦截属于双保险。很多面试题里问Vue动态路由怎么实现其实就是上面这套逻辑理解原理后不管换什么前端框架这套思路都通用。5.3 路由传参的几种方式与使用场景路由传参用不好会出现刷新页面参数丢失的问题这是个经典坑。Vue Router 4 支持三种传参方式各有的适用场景。// 方式一query 字符串传参 router.push({ path: /detail, query: { id: 1 } }) // URL 显示/detail?id1 // 获取route.query.id // 方式二params 传参配合路由定义 // 路由定义中{ path: /detail/:id, component: DetailView } router.push({ name: detail, params: { id: 1 } }) // URL 显示/detail/1 // 获取route.params.id // 方式三state 传参 router.push({ name: detail, state: { fromList: true } }) // URL 不变数据存在 history.state 中三种方式的注意事项query方式的参数会出现在URL里刷新不丢适合传简短标识。params方式必须与路由路径的参数定义配合使用而且如果跳转时用path而不是nameparams会被直接忽略——这是最常见的坑。state方式传的数据不会暴露在URL里适合传对象、列表快照这类大体积或敏感数据但刷新页面后state也会丢失需要结合业务场景判断。我实际项目中有一套稳妥组合列表页跳详情页传params带ID详情页根据ID重新请求数据跨页面传筛选条件时用query保证用户刷新后筛选条件还在用户勾选状态这类临时数据用pinia管理不依赖路由。6. 高频踩坑实录与项目增量实践6.1 开发期避坑速查表下面这些坑是我在带团队和做项目过程中反复遇到的整理成一张速查表能帮你在开发期避开大量无效排查时间。这些内容对应了 vscode中点vue标签没有跳转、vue div超出隐藏、vue image能显示pdf吗 等热词背后实实在在的问题场景。问题现象根因解决方案明明改了代码浏览器页面不更新Vite热更新偶发失效重启npm run dev或按Ctrl Shift R强刷在VSCode里点击组件标签不能跳转到组件文件缺少Volar插件安装Vue官方推荐的 Volar 扩展Vue Language Features禁用旧的 Vetur打包后静态资源404资源路径使用绝对路径部署时不在根目录在vite.config.js里设置base: ./图片超出容器显示溢出没给图片加尺寸约束用max-width: 100%; height: auto;控制图片行为页面能打开但刷新后404使用的是 history 模式路由配合的是静态服务器改用 hash 模式createWebHashHistory()或配置服务器重写组件样式互相污染没写scoped或者样式权重冲突每个组件style都加scoped全局样式只放src/assets里管理想要在页面中展示PDF文件浏览器不能直接渲染PDF内容是误区用iframe :srcpdfUrl展示或集成pdf.js/vue-pdf-embed需要播放m3u8格式的视频原生video不支持m3u8格式使用hls.js需配合打包配置或video.js加videojs-contrib-hls子组件修改了props传入的对象Vue警告状态不可预测子组件内只读props修改时emit事件让父组件处理动态渲染表头或表单字段不生效响应式数组/对象变更方式不对用Object.assign/ref的.value正确替换整个数组或对象我挑两个展开聊。第一个是刷新404的问题。开发模式下npm run dev一切正常是因为Vite开发服务器做了路由重写的处理但打包部署到Nginx或者SpringBoot的静态文件目录后你在根路径能访问点/user/list之后一刷新服务器收到一个/user/list的请求找不到对应文件就报404了。解决办法有两种一种是用hash模式URL变成/user/list#/page路由信息在#后面不会发给服务器刷新自然没问题另一种是让后端把所有的前端路由请求都重写到index.html由前端路由接管。我自己的习惯是纯前端项目用history模式加服务器重写因为URL更友好要往SpringBoot里打包的场景直接用hash模式省去配置后端的麻烦。第二个是往SpringBoot打包的问题。Vue项目构建产物是dist目录里的一组静态文件打包进SpringBoot无非是两步第一步把dist里的内容放到SpringBoot的src/main/resources/static目录下第二步按上面说的处理路由模式问题。但这里有个最隐蔽的坑——静态资源路径。Vite默认base: /意味着它生成的资源引用是绝对路径比如/assets/index-abc123.js部署到服务器根目录没问题但SpringBoot内部处理静态资源的方式略有不同如果你把dist放到一个子路径下所有资源都会404。解决办法就是在vite.config.js里设置相对路径// vite.config.js export default defineConfig({ base: ./, // ...其他配置 })这样生成的资源引用都是相对路径无论部署到什么目录都不会出问题。用相对路径有时字体文件和图片的引用会需要注意嵌套层级但基本都能解决。6.2 vite.config.js 开发代理解除跨域噩梦前端开发中跨域问题绕不开。我们本地跑在localhost:5173后端接口在localhost:8080浏览器因为同源策略的限制前端直接请求后端接口会被拦截。用代理是开发环境最优雅的解法。在vite.config.js里配置export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } } })这个配置是什么意思前端请求/api/user/list时Vite开发服务器会把请求转发到http://localhost:8080/user/listrewrite负责把/api前缀去掉。changeOrigin: true保证请求头中Host字段被修改为目标地址防止后端校验时因为Host不一致而报错。配置好之后前端代码里统一写相对路径/api/xxx请求就不存在跨域问题了。等到部署上线时后端再做一个统一的网关转发或者直接配置同源访问。这里我给新手一个建议项目里所有的接口请求路径都以/api开头统一管理后续做代理、做网关重写、做Mock切换都方便。6.3 从业务场景出发的页面级调试技巧Vue3配合Vite的开发调试体验相当好但很多新手不知道利用好浏览器和Vue生态提供的工具。我实际工作中依赖这几个调试手段Vue Devtools浏览器插件查看组件树、props/emit流向、Pinia状态实时值。调试组件通信问题时我第一件事永远是开Devtools看组件的props到底收到了什么。浏览器Network面板确认接口请求是否发出、参数是否对、响应是否符合预期。很多页面没数据的排查都可以从这里入手。Vite的debugger配合源码定位在script setup里直接写debugger浏览器会停在这一行配合Vue的源码映射source map能从编译后的代码准确映射回源码位置。移动端调试如果用手机浏览器访问开发环境页面在电脑上打开chrome://inspect进行远程调试真机效果一眼看清。调试姿态比工具更重要。遇到问题先定位是请求层、渲染层还是交互层出了问题一层层缩小范围不要盲目改代码。这是我带团队时反复强调的排查思路也是工作效率差距的来源。6.4 实战路线从简单组件到完整后台页面的进阶路径这篇文章最后我给出一条经过验证的学习与实践路径从独立编写组件到整合出一个完整后台页面。按照这个节奏走下去大概三四周就能对Vue3工程化开发形成完整的肌肉记忆。第一步第1周用脚手架搭工程反复练习组件的基础通信props、emit、v-model写一个常见的评论组件或者卡片列表组件把所有通信方式都实际用一遍。熟悉vue-router的基本配置、跳转、传参。第二步第2周引入Pinia做全局状态练习做一个简单的购物车功能理解状态管理解决什么问题、什么时候才需要它。同时开始使用Element Plus组件库练习列表页和表单页的组合搭建。第三步第3周做一个完整的管理后台页面包含登录、路由守卫拦截、Token管理、权限按钮控制、列表搜索、分页、弹窗表单。重点体验没有权限时整个功能如何优雅降级的逻辑以及完整的请求、状态、渲染链路。第四步第4周学习一些进阶主题——组件逻辑复用composables、自定义指令、Mock数据模拟、Vite打包优化同时研究怎么把项目集成到后端框架中部署上线。每一步都要真实写代码不要只看不练。这个学习路径覆盖了热词里头 vue入门、vue项目实战、vue前端面试题 提到的大部分核心知识点面试和工作中遇到的场景基本都能应对。另外学习过程中阅读优秀源码是提升最快的途径之一。去GitHub找一个开源的Vue3后台管理系统比如 vue-pure-admin、vue-vben-admin把项目clone下来重点看它们的目录结构怎么组织、权限路由怎么实现、组件怎么拆分、API层怎么做封装。不要怕项目复杂挑一个模块精读即可比看100篇教程都有效。最后再分享一个我在实际项目里反复验证的经验组件化的边界不是一次就能分好的随着业务迭代组件拆分方案也需要持续重构。第一次开发时觉得合适的拆分可能三个月后随着新功能的加入就不合适了。重构组件不是推翻重来而是把职责重新划分、把公共部分抽出来。代码没有完美的只有当前业务阶段下够用且好维护的。胆子大一点多拆分多重构这个手感是练出来的。
返回列表