vue中的路由 Router
vue路由的官网中讲述的知识点比较精细 但是针对不同环境所使用的侧重点不同 以vue脚手架为例
总结常用的三点 路由传参 路由守卫 以及路由跳转
1. 路由跳转
路由跳转可以分为两种 一种是使用标签属性 另一种是编程式路由
首先来说标签属性:router-link
- 不带参数
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">
// name,path都行, 建议用name
// 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。
2.带参数
<router-link :to="{name:'home', params: {id:1}}">
// params传参数 (类似post)
// 路由配置 path: "/home/:id" 或者 path: "/home:id"
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 $route.params.id
// script 取参 this.$route.params.id
<router-link :to="{name:'home', query: {id:1}}">
// query传参数 (类似get,url后面会显示参数)
// 路由可不配置
// html 取参 $route.query.id
// script 取参 this.$route.query.id
其次是编程式导航
this.$router.push() (函数里面调用)
- 不带参数
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
- query传参
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
// html 取参 $route.query.id
// script 取参 this.$route.query.id
- params传参
this.$router.push({name:'home',params: {id:'1'}}) // 只能用 name
// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,
// 不配置path ,第一次可请求,刷新页面id会消失
// 配置path,刷新页面id会保留
// html 取参 $route.params.id
// script 取参 this.$route.params.id
this.$router.replace()
(用法同上,push)
this.$router.go(n) ()
this.
r
o
u
t
e
r
.
g
o
(
n
)
:
向
前
或
者
向
后
跳
转
n
个
页
面
,
n
可
为
正
整
数
或
负
整
数
∗
∗
注
:
t
h
i
s
.
router.go(n):向前或者向后跳转n个页面,n可为正整数或负整数** 注: this.
router.go(n):向前或者向后跳转n个页面,n可为正整数或负整数∗∗注:this.router.push:跳转到指定url路径,并想history栈中添加一个记录,点击后退会返回到上一个页面
this.
r
o
u
t
e
r
.
r
e
p
l
a
c
e
:
跳
转
到
指
定
u
r
l
路
径
,
但
是
h
i
s
t
o
r
y
栈
中
不
会
有
记
录
,
点
击
返
回
会
跳
转
到
上
上
个
页
面
(
就
是
直
接
替
换
了
当
前
页
面
)
t
h
i
s
.
router.replace:跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面 (就是直接替换了当前页面) this.
router.replace:跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面(就是直接替换了当前页面)this.router.go(n):向前或者向后跳转n个页面,n可为正整数或负整数
2. 路由传参
query和params区别
query类似 get, 跳转之后页面 url后面会拼接参数,类似?id=1, 非重要性的可以这样传,
密码之类还是用params刷新页面id还在
params类似 post, 跳转之后页面 url后面不会拼接参数 , 但是刷新页面id 会消失。
当query传递的是一个对象时,需要这样传,否则刷新页面。会发现对象完全变了。成了一个"[object Object]"
let data = JSON.stringify(result) // result传递的query参数。我们转为string
this.$router.push({path: '/wx/detail', query: {res: data}})
// 详情页获取
let data = JSON.parse(this.$route.query.res)
this.result = Object.assign({}, data)
动态路由传参
{
path: "/index/:id",
component: () => import("@/views/Index.vue"),
},
超级重点:一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。
使用动态路由时 参数直接使用字符串拼接的方式拼接在地址后
this.$router.push({
path: "/index/" + val,
});
3. 路由守卫
路由的导航守卫 又叫做路由的钩子函数(生命周期函数)
就是在跳转页面的 时候把 路由拦下来 做一些操作 再放行
一共有三种
第一种是全局守卫
beforeEach 路由进入之前
afterEach 路由进入之后
第二种 组件内守卫
beforeRouteEnter 路由进入之前
beforeRouteUpdate 路由更新之前
beforeRouteLeave 路由离开之前
第三种
独享守卫
beforeEnter 路由进入之前
有三个参数
to from next
next 这个参数 在路由 3.x 版本的时候 是必须的
但是到了路由 4.x 版本的时候 next 参数变成可选的了
一般来说 vue2 搭配 3.x 的路由
vue3 搭配 4.x 的路由
比如说 购物车页面只有登陆的才能访问 我们可以用组件级守卫守卫购物车页面
如果已经登陆存的有 token 的话 就继续访问这个页面 如果没有登陆的话就会跳转到登陆页面
beforeRouteEnter(to, from, next) {
if (localStorage.getItem("token")) {
next();
} else {
next("/login");
}
next 参数 除了括号里可以是空和路径之外 还可以是一个回调函数(回调函数就是一个被作为参数传递的函数)
比如说 token 被存进 vuex 里就能这么写:
beforeRouteEnter(to, from, next) {
// if (localStorage.getItem("token")) {
// next();
// } else {
// next("/login");
// }
next((vm) => {
// vm就是 这个组件实例 就是this
if (vm.$store.state.token) {
next();
} else {
next("/login");
}
});
},
路由守卫详解
-
全局前置守卫(beforeEach)
在路由跳转前触发,这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。 -
全局解析守卫(beforeResolve)
这个个钩子和beforeEach类似,也是路由跳转前触发,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,即在 beforeEach 和 组件内beforeRouteEnter 之后,afterEach之前调用。 -
全局后置钩子(afterEach):
和beforeEach相反,它是在路由跳转完成后触发,它发生在beforeEach和beforeResolve之后,beforeRouteEnter(组件内守卫)之前。这些钩子不会接受next函数也不会改变导航本身 -
路由独享守卫(beforeEnter):
和beforeEach完全相同,如果两个都设置了,beforeEnter则在beforeEach之后紧随执行。在路由配置上直接定义beforeEnter守卫 -
组件内的守卫:
beforeRouteEnter:
该钩子在全局守卫beforeEach和独享守卫beforeEnter之后,全局beforeResolve和全局afterEach之前调用,要注意的是该守卫内访问不到组件的实例,也就是this为undefined。因为它在组件生命周期beforeCreate阶段触发,此时的新组件还没有被创建。在这个钩子函数中,可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。beforeRouteUpdadte:
在当前路由改变时,并且该组件被复用时调用,可以通过this访问实例。beforeRouteLeave:
导航离开该组件的对应路由时调用,可以访问组件实例this。这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过next( false )来取消。
完整的导航解析流程
-
导航被触发
-
调用 失活 组件守卫:beforeRouteLeave
-
调用 失活 组件:deactivated(keep-alive下才有)
-
调用全局守卫:beforeEach
-
调用 重用 组件守卫:beforeRouteUpdate
-
调用路由守卫:beforeEnter
-
解析异步路由组件
-
调用 激活 组件守卫:beforeRouteEnter
-
调用全局守卫:beforeResolve
-
导航被确认
-
调用全局守卫:afterEach
-
触发DOM更新(以下顺序成立前提:子组件没有通过v-if状态false变为true)
(-------同步加载子组件,即import Test from “./components/Test.vue”-------) -
父组件: beforeCreate
-
父组件: created
-
父组件: beforeMount
-
子组件: beforeCreate
-
子组件: created
-
子组件: beforeMount
-
父组件前置守卫回调函数:beforeRouteEnter next
-
失活父组件: beforeDestroy
-
失活子组件: beforeDestroy
-
失活子组件: destroyed
-
失活父组件: destroyed
-
子组件: mounted
-
父组件: mounted
-
父组件: activated(keep-alive下才有)
4. 额外补充
vue-router中 $router 和 $route有啥区别:
- this.$router表示全局,是router构造方法的实例
- this.$route表示的是当前页面的路由信息
**1.$route.path**
字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
**2.$route.params**
一个 key/value 对象,包含了 动态片段 和 全匹配片段,
如果没有路由参数,就是一个空对象。
**3.$route.query**
一个 key/value 对象,表示 URL 查询参数。
例如,对于路径 /foo?user=1,则有 $route.query.user == 1,
如果没有查询参数,则是个空对象。
**4.$route.hash**
当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点
**5.$route.fullPath**
完成解析后的 URL,包含查询参数和 hash 的完整路径。
**6.$route.matched**
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
**7.$route.name 当前路径名字**
**8.$route.meta 路由元信息
路由重定向
const routes = [{ path: '/home', redirect: '/' }]
重定向的目标也可以是一个命名的路由:
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
甚至是一个方法,动态返回重定向目标:
const routes = [
{
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
return { path: '/search', query: { q: to.params.searchText } }
},
},
{
path: '/search',
// ...
},
]
请注意,导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在上面的例子中,在 /home 路由中添加 beforeEnter 守卫不会有任何效果。
在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由:如果一个路由记录有 children 和 redirect 属性,它也应该有 component 属性。
vue的路由模式⼀共有两种,分别是哈希和history
他们的区别是hash模式不
会包含在http请求当中,并且hash不会重新加载⻚⾯,⽽使⽤history模式的话,如果前端的url和后端发起请求的url不⼀致的话,会 报404错误,所以使⽤history模块的话我们需要和后端进⾏配合.
history的原理就是利⽤html5新增的两个特性⽅法,分别是psuhState和replaceState来完成的
关于脚手架中常用的路由理念就总结到这里了 有不足的地方还希望评论指出