Vue-Router
Vue3官网>生态系统>Vue-Router- router.vuejs.org/zh/introduc…
路由
-
搭建路由
-
下包:
npm install vue-router@4##### Vue2和Vue3路由版本区别 Vue2:router@3 版本 Vue3:router@4 版本 -
配置路由表
-
导入路由
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router' -
配置路由表
export default createRouter({ /* history History => 没有#号 HashHistory => 带#号 */ history:createWebHashHistory(), routes:[ { path:'/home', component:Home // 组件 }, { path:'/about', component:About // 组件 } ] })
-
-
在
main.js中全局引入路由,并声明使用-
引入路由
import router from './router' -
声明使用
app.use(router)
-
-
-
路由在全局声明使用后
-
在全局挂载了两个组件
-
<RouterLink></RouterLink>to:路由的路径
<RouterLink to="/home"></RouterLink>使用一个自定义组件`<router-link />`来代替`<a />`创建链接 这使得Vue-Router可以在不重新加载页面的情况下更改URL -
<RouterView></RouterView>显示与url对应的组件。你可以把它放在任何地方,以适应你的布局
-
-
所有组件都可以访问
this.$router和this.$routethis.$router:路由实例对象this.$route:当前路由对象
-
路由模式
-
createWebHashHistory带`#`号 hash使用的window.onhashchange事件来监听URL的路径的变化 -
createWebHistory不带`#`号 使用pushState,在不刷新页面的情况下,添加个历史记录 使用replaceState,在不刷新页面的情况下,替换个历史记录 使用onpopState,监听的前进和后退 Vue和React路由使用 history 库 history在上线时,如果进行额外的配置,那么会出现404的问题
命名视图
-
同时 (同级) 展示多个视图,而不是嵌套展示
-
路由:
routes:[ { path:"/", components:{ default:Home, // 默认视图 the:About // 命名视图 } } ] -
使用:
<RouterView></RouterView> <!-- 显示默认视图 --> <RouterView name="the"></RouterView> <!-- 命名视图 -->
路由懒加载(性能优化)
- 路由懒加载:将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才会加载对应组件的代码块
- 语法:
()=>import ('组件路径')
export default createRouter({
history:createWebHistory(),
routes:[
{
path:'/home',
component:()=>import ('../views/home.vue')
},
{
path:'/about',
component:()=>import ('../views/about.vue')
}
]
})
图片懒加载(性能优化)
<img src="默认图片" data-src="真的图片">- 最开始,使用一张默认的图片,用这种图片展示所有的图片。
- 当我们滚动条下来的,将能看到的哪几张图片给展示出来,使用真正的图片替换原来的默认的图片
# 后面项目中再讲
命名路由
-
除了
path外,可以为路由添加name -
优点:
- 没有硬编码的
url params的自动编码/解码- 防止你
url中出现打字错误 - 绕过路径排序
// 命名路由 const routes = [ { path: '/user/:username', name: 'user', component: User, }, ]<router-link :to="{ name: 'user', params: { username: 'erina' }}" />router.push({ name: 'user', params: { username: 'erina' } }) - 没有硬编码的
路由别名
alias:给路由配置多个访问的名称
routes:[
{
path:'/home',
component:News,
alias:'/hh',
// alias:['/n','/w','/ws']// 配置多个用数组
},
{
path:'/about',
component:News,
alias:['/aa','/bb','/oo','/uu','/tt'],
}
]
重定向
-
redirect:重定向到哪个路由routes:[ { path:'/', redirect:'/home' } ]
编程式导航
-
声明式
<router-link :to="..."><RouterLink to="/home">Home</RouterLink> -
编程式
router.push(...)使用js实现跳转
$router
push(路由url):带历史记录的跳转replace(路由url):不带历史记录的跳转forward():前进一页back():后退一页go(n):前进/后退|n|页getRoutes():获取路由表的完整记录
this.$router.push("/home") // 有记录跳转
this.$router.replace("/home") // 无记录跳转
this.$router.forward() // 前进后退
this.$router.back() // 后退
this.$router.go(2) // 前进2页
this.$router.go(-2) // 后退2页
this.$router.getRoutes() // 获取路由表的完整记录
# Vue组合式api
import { useRouter } from "vue-router"; // 引入路由表
let router = useRouter() // 使用
$route
path:路径fullpath:全路径query:query参数params:params参数matched:包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 的数组)
# Vue组合式api
import { useRoute } from "vue-router"; // 引入路由对象
let route = useRoute() // 使用
路由传参
query参数
-
语法1:字符串、参无
this.$router.push('/home') -
语法2:字符串、带query参数
this.$router.push('/home?name=张三&age=18&gender=男') -
语法3:对象、无参
this.$router.push({path:'/home'}) -
语法4:对象、带query参数
this.$router.push({path:'/home',query:{name:'张三',age:18,gender:'男'}}) -
语法5:对象、使用name、无参
this.$router.push({name:'home'}) -
语法6:对象、使用name、带query参数
this.$router.push({name:'home',query:{name:'张三',age:18}})
params参数
-
语法1:字符串、params参数、借助路由表
this.$router.push("/home/张三/18") -
语法2:对象、params参数
this.$router.push({ path: '/home', params: { name: "张三", age: 18, gender: '男' } })`!注意:params与path不能一起共用,否则params失效` -
语法3:综合
this.$router.push({ name: 'home', query: { username: "张三" }, params: { age: 18 } })
`指定params参数可传可不传`
// 在参数后加`?`号
// 例:路由表中:
{
path:'/home/:id?'
}
嵌套路由
-
语法1:
// 一级路由 routes:[ { path:'/home', component:Movie, // 二级路由 children:[ { path:'/home', redirect:'/home/list' }, { path:'/home/list', component:List }, { path:"/home/about", component:About } ] }, ] -
语法2:
// 一级路由 routes:[ { path:'/home', component:Movie, // 二级路由 children:[ { path:'list', component:List }, { path:"about", component:About } ] }, ]
导航守卫
-
导航守卫:路由跳转的保安
-
全局导航守卫
* 但凡有路由跳转,都会触发 * 书写位置:在路由表中与`createRouter`平级beforeEach(全局前置守卫)afterEach(全局后置守卫) 参数next无效果beforeResolve(全局解析守卫)用不到
🌰: router.beforeEach((to,from,next)=>{ console.log("全局前置守卫:",to,from); next() // 放行 }) router.afterEach((to,from,next)=>{ console.log("全局后置守卫:",to,from); next() // 放行 }) -
路由独享守卫
-
beforeEnter* 在当前路径下跳转进行拦截,专门针对某一个路由 * 书写位置:路由表内🌰: const router = createRouter({ history: createWebHistory(), { path:'/home/list', component:List, beforeEnter:(to,from)=>{ console.log("路由独享守卫:",to,from); } } })
-
-
组件内守卫
beforeRouterEnter:跳转到组件之前,注意: 不能使用thisbeforeRouterUpdate:当前组件跳转自己(路由的参数发生改变)触发beforeRouterLeave:组件离开触发
* 书写位置:组件内与`选项`平级🌰: //跳转该组件之前 beforeRouteEnter(to,from,next){ console.log("组件跳转之前:",to,from); next(); }, //组件跳转自己,路由参数发生改边 beforeRouteUpdate(to,from){ console.log("跳转自己:",to,from); }, //组件离开 beforeRouteLeave(to,from){ console.log("组件离开:",to,from); } -
导航守卫的形参
-
to:跳转目标 -
from:跳转来源 -
next:拦截/放行next(),next(true)=> 放行next(路由url)=> 强制跳转url路径next(false)=> 拦截
##### Vue2与Vue3在导航守卫中形参 next 的区别 Vue2: next(),next(true) => 放行 next(路由url) => 强制跳转路径 next(false) => 拦截 Vue3: next选填,如果没写next,那就return替换next 默认没写return,表示放行 return true => 放行 return false => 拦截 return 路由url => 强制跳转url地址
-
路由元信息
- 希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等
- 可以通过接收属性对象的
meta属性来实现
🌰:
const routes = [
{
path: '/home',
component: Home,
// 只有经过身份验证的用户才能创建帖子
meta: { requiresAuth: true }
}
]
滚动行为
-
路由跳转,始终滚动到顶部
* 书写位置:路由表中与`routes`平级scrollBehavior(to, from, savedPosition) { return { top: 0 } }