先搞懂,Yarn和Vue Router各自是干啥的?
p>不少刚接触Vue生态的同学,常会疑惑「vue router yarn怎么用?」,毕竟Vue Router是单页应用实现路由跳转的核心工具,Yarn又是高效的包管理利器,把两者结合好能让项目依赖管理更丝滑,这篇文章从安装到实战,一步步拆解怎么用Yarn玩转Vue Router,哪怕是新手也能跟着踩稳每一步~
要把工具用顺手,得先明白它们的角色。
Yarn是前端包管理器,就像“购物管家”——帮你从npm仓库里挑版本、下依赖,还能把每个包的版本和依赖关系“锁死”在yarn.lock
里,团队协作时,别人拉代码后执行yarn install
,能和你本地装的包版本完全一致,避免“我这能跑,你那报错”的尴尬。
Vue Router是Vue官方的路由工具,堪称SPA(单页应用)的“导航员”——用户点按钮、输网址时,它决定显示哪个页面组件、怎么传参、要不要权限验证,比如做个博客,用户点“文章列表”显示列表组件,点“文章详情”显示详情组件,这些跳转逻辑全靠Vue Router实现。
第一步:用Yarn安装Vue Router,版本咋选?
很多同学第一次装就栽在版本匹配上,先看自己项目用的Vue版本:打开package.json
,看"vue"
的版本号——要是"^2.6.14"
这种,属于Vue2,得装Vue Router 3.x;要是"^3.2.0"
或更高,是Vue3,得装Vue Router 4.x。
操作很简单:打开终端,cd
到项目根目录,输入对应命令:
- Vue2 + Vue Router 3:
yarn add vue-router@3
- Vue3 + Vue Router 4:
yarn add vue-router@4
敲完回车,Yarn会自动下载依赖,同时更新package.json
和yarn.lock
,装完后,去node_modules
里看看有没有vue-router
文件夹,再检查package.json
里的依赖版本对不对,要是之前装错版本了,先执行yarn remove vue-router
把旧的删掉,再重新装对应版本就行~
这里得唠叨一句:yarn.lock
文件很重要!它能把每个包的版本、依赖关系锁死,团队里其他人拉代码后,执行yarn install
能保证装的包版本和你完全一样,所以装完Vue Router后,记得把yarn.lock
也提交到代码仓库哦~
安装完咋配置?Vue2和Vue3配置差异在哪?
装好了包,接下来得让Vue“认识”Vue Router,这步配置错了,页面准保白屏!分Vue2和Vue3两种情况,咱们一个一个说~
Vue2 配置流程
-
新建路由文件:在
src
目录下建个router
文件夹,里面放index.js
。 -
写配置代码:
import Vue from 'vue' import VueRouter from 'vue-router' // 引入页面组件(比如Home和About) import Home from '../views/Home.vue' import About from '../views/About.vue' // 告诉Vue要使用VueRouter插件 Vue.use(VueRouter) // 定义路由规则:path对应网址路径,component对应要显示的组件 const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] // 创建路由实例,把规则传进去 const router = new VueRouter({ routes // 等价于routes: routes }) // 导出路由实例,给main.js用 export default router
-
挂载到Vue实例:打开
src/main.js
,引入刚写的router:import Vue from 'vue' import App from './App.vue' import router from './router' // 引入路由配置 new Vue({ router, // 把路由实例注入Vue,这样所有组件都能拿到$router和$route render: h => h(App) }).$mount('#app')
在
App.vue
里加<router-view>
,用来显示匹配的组件:<template> <div id="app"> <!-- 路由出口:这里显示当前路径对应的组件 --> <router-view></router-view> </div> </template>
Vue3 配置流程(因Vue3用createApp
,配置逻辑变了)
Vue3里,Vue Router的创建方式更“函数式”,步骤如下:
-
新建路由文件:同样在
src/router
下建index.js
,但引入的API变了:import { createRouter, createWebHistory } from 'vue-router' // 引入Vue3的组件(写法和Vue2类似,但 reactivity 机制不同) import Home from '../views/Home.vue' import About from '../views/About.vue' // 定义路由规则,和Vue2一样 const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] // 创建路由实例:用createRouter,配置history模式(还有createWebHashHistory是hash模式) const router = createRouter({ history: createWebHistory(), // 对应history模式,URL没有# routes }) export default router
-
挂载到App:打开
src/main.js
,Vue3用createApp
来创建应用:import { createApp } from 'vue' import App from './App.vue' import router from './router' const app = createApp(App) app.use(router) // 把路由实例注入应用 app.mount('#app')
-
添加路由出口:同样在
App.vue
里加<router-view>
,用法和Vue2一样~
这里最容易搞混的是「history模式」和「hash模式」:
history
模式:URL长这样 →http://xxx.com/about
,好看但需要后端配合(否则刷新会404);hash
模式:URL长这样 →http://xxx.com/#/about
,带个,但兼容性好,不用后端配置。
根据项目需求选,一般前端项目优先选history
,后端配合一下就行~
实战场景:用Yarn管好依赖,玩转路由功能
装完配好,得真正用起来!下面挑几个开发中常用的路由功能,结合代码讲讲咋实现~
场景1:动态路由(比如用户详情页)
需求:点击用户列表项,跳转到/user/123
这样的页面,显示用户ID为123的信息。
步骤:
-
配置动态路由规则:在
router/index.js
里加一条:{ path: '/user/:id', // :id是动态参数 component: User }
-
新建User.vue组件,读取动态参数:
<template> <div> <!-- 用$route.params.id拿到路径里的id --> 当前用户ID:{{ $route.params.id }} </div> </template>
-
跳转方式:可以用
<router-link>
或者编程式导航,比如列表里的按钮:<!-- 用<router-link>跳转 --> <router-link :to="'/user/'+user.id">查看用户{{ user.id }}</router-link> <!-- 用编程式导航(按钮点击) --> <button @click="goUser(user.id)">查看</button> <script> export default { methods: { goUser(id) { this.$router.push('/user/' + id) } } } </script>
场景2:嵌套路由(比如后台管理系统的布局)
需求:后台页面有个公共布局(侧边栏+顶栏),不同菜单项对应不同子页面,比如/dashboard/analysis
和/dashboard/monitor
。
步骤:
- 建布局组件:先建
DashboardLayout.vue
,里面包含侧边栏、顶栏,还有<router-view>
给子路由用:<template> <div class="dashboard-layout"> <aside>侧边栏</aside> <header>顶栏</header> <main> <!-- 子路由出口 --> <router-view></router-view> </main> </div> </template>
- 配置嵌套路由规则:在
router/index.js
里,给DashboardLayout
加children
:{ path: '/dashboard', component: DashboardLayout, children: [ { path: 'analysis', component: Analysis }, // 对应/dashboard/analysis { path: 'monitor', component: Monitor }, // 对应/dashboard/monitor { path: '', redirect: 'analysis' } // 访问/dashboard时,默认跳转到analysis ] }
- 现在访问
/dashboard
,会先渲染DashboardLayout
,然后根据子路径渲染Analysis
或Monitor
组件,完美实现布局复用~
场景3:路由守卫(权限控制)
需求:进入个人中心页面(/profile
)前,判断用户是否登录,没登录就跳转到登录页。
步骤:用全局前置守卫router.beforeEach
:
在router/index.js
里,配置完路由实例后加:
router.beforeEach((to, from, next) => { // 判断要去的页面是不是/profile if (to.path === '/profile') { // 假设用isLogin()函数判断是否登录(实际项目里可能是token存在) if (isLogin()) { next() // 已登录,放行 } else { next('/login') // 没登录,跳转到登录页 } } else { next() // 其他页面,直接放行 } })
这样就能在用户访问受保护页面时,自动做权限校验~
这些功能能跑通,离不开Yarn把Vue Router版本锁死,要是依赖版本乱了,比如Vue Router 3和Vue3混用,路由守卫可能直接报错,所以用Yarn管理依赖,版本稳定是前提,开发时少踩版本兼容的坑~
踩坑时刻:那些Yarn+Vue Router的常见问题咋解决?
开发中遇到问题别慌,先看报错信息,再对应解决~
坑1:安装后报错“Vue.use is not a function”
现象:启动项目后,控制台报错Vue.use is not a function
。
原因:Vue3里没有Vue.use
这个API了!你可能在Vue3项目里,还按照Vue2的方式写了Vue.use(VueRouter)
。
解决:Vue3要用app.use(router)
,检查main.js
里的代码:
// 错误写法(Vue2的) import Vue from 'vue' Vue.use(router) // 正确写法(Vue3的) import { createApp } from 'vue' const app = createApp(App) app.use(router)
坑2:路由跳转后,页面数据不更新
现象:比如从/user/1
跳转到/user/2
,组件里的数据还是用户1的。
原因:Vue Router为了性能,会复用相同组件,导致组件的created
、mounted
钩子不重新执行。
解决:两种方法选一个:
① 给<router-view>
加key
,强制组件重新渲染:
<router-view :key="$route.fullPath"></router-view>
② 在组件里监听$route
变化:
export default { watch: { '$route'(to, from) { // to是目标路由,from是来源路由 this.fetchData(to.params.id) // 重新请求数据 } } }
坑3:Yarn.lock冲突,团队协作拉代码后安装失败
现象:git pull
后执行yarn install
,报错依赖冲突。
原因:多人开发时,不同分支的yarn.lock
对同一包的版本记录不一致。
解决:
- 先执行
yarn upgrade vue-router
,让Yarn重新解析依赖,生成新的yarn.lock
; - 解决代码冲突后,把更新后的
yarn.lock
提交到仓库,确保所有人版本一致。
坑4:打包后路由404(history模式)
现象:开发时路由正常,打包后打开dist/index.html
,刷新页面就404。
原因:history
模式下,前端路由依赖HTML5 History API,服务器没配置的话,会把路由当成真实路径,找不到对应的文件。
解决:让后端配置“前端路由 fallback”,以Nginx为例,在配置文件里加:
location / { try_files $uri $uri/ /index.html; }
这样不管访问什么路径,都会跳转到index.html
,由前端路由接管~
进阶玩法:Yarn Workspace+Vue Router,大型项目咋玩?
要是你在做大型项目,或者多个项目要共享组件,用Yarn Workspace搞monorepo
(单仓多包)结构超方便!比如一个前端项目分多个包:app-frontend
(Vue应用)、ui-components
(公共组件库),其中app-frontend
依赖Vue Router和ui-components
。
步骤1:初始化Yarn Workspace
在项目根目录新建package.json
,开启workspace:
{ "name": "my-monorepo", "private": true, // 私有仓库,不发布到npm "workspaces": [ "packages/*" // 所有packages下的子包都是workspace成员 ] }
然后建packages
文件夹,里面放app-frontend
和ui-components
:
my-monorepo/
├─ packages/
│ ├─ app-frontend/
│ ├─ ui-components/
步骤2:在app-frontend里用Yarn安装Vue Router
进入app-frontend
目录,执行yarn add vue-router@4
(假设是Vue3项目),Yarn会自动把依赖装到根目录的node_modules
,或者子包的node_modules
(根据hoist规则),但yarn.lock
在根目录统一管理,保证所有子包的依赖版本一致。
步骤3:跨包使用组件(比如ui-components里的导航栏)
在ui-components
里开发公共组件Navbar
,然后在app-frontend
的package.json
里依赖ui-components
:
{ "dependencies": { "ui-components": "workspace:*" // 表示依赖当前workspace里的ui-components } }
执行yarn install
后,Yarn会自动把ui-components
链接到app-frontend
的node_modules
,这样在app-frontend
的路由组件里,就能import { Navbar } from 'ui-components'
,实现组件复用~
好处:版本统一+依赖共享
- 所有子包的Vue Router版本由根
yarn.lock
控制,不会出现“这个包用4.0,那个包用4.1”的情况; - 公共依赖(比如Vue、Vue Router)只装一份,减少
node_modules
体积; - 团队协作时,只要拉取根目录的
yarn.lock
,所有子包的依赖都能一键装好,不用每个包单独npm install
。
这种玩法适合中大型团队或多项目复用场景,Yarn Workspace把依赖管理的优势拉满,配合Vue Router打造高可维护的前端架构~
把Yarn和Vue Router玩明白,路由管理更丝滑~
从安装时选对版本,到配置时区分Vue2和Vue3,再到实战里玩转动态路由、嵌套路由、权限控制,最后用Yarn Workspace搞定大型项目的依赖管理——这一套流程走下来,你会发现Yarn和Vue Router的结合,不止是“装个包”那么简单,更是让项目从开发到协作都更高效的关键。
要是你刚开始练手,建议先从简单的单页应用做起:用Yarn装Vue Router,配个首页和关于页,试试<router-link>
和编程式导航;遇到问题别慌,回头看看常见坑的解决方法,多改几次代码就熟了,等项目大了,再尝试Yarn Workspace的玩法,体验monorepo
的爽感~
工具是为了解决问题的,把Yarn和Vue Router的特性用起来,前端路由开发能省不少事儿~现在就打开终端,挑个小项目练起来吧!
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。