一:路由的基本概念
1.1后端路由:根据不同的url返回不同的资源
后端路由.png
1.2SPA
SPA由来.png
1.3前端路由
前端路由.png
1.4实现简易的前端路由
监听hash变化.png
简单代码示例:
html:
<div id="app">
<a href="#/zhuye">主页</a>
<a href="#/keji">科技</a>
<a href="#/caijing">财经</a>
<a href="#/yule">娱乐</a>
<component :is="fragment"></component>
</div>
js:
<script>
//定义备切换的组件
const zhuye = {
template: "<div>主页面</div>",
};
const keji = {
template: "<div>科技页面</div>",
};
const caijing = {
template: "<div>财经页面</div>",
};
const yule = {
template: "<div>娱乐页面</div>",
};
//获取vue示例
var vm = new Vue({
el: "#app",
data: {
fragment: "zhuye",
},
components: {
zhuye,
keji,
caijing,
yule,
},
mounted: function () {
var that = this;
window.addEventListener(
"hashchange",
function (e) {
console.log(location.hash);
that.fragment = location.hash.slice(2);
console.log(that.fragment);
},
false
);
},
});
</script>
效果预览:
二:Vue Router
vue中mode hash 和 history的区别
vue-router功能简述.png
2.1基本使用步骤
①引入vue-router
引入库文件.png
②添加路由链接
添加路由链接.png
③添加路由填充位
添加路由填充位.png
④定义路由组件
定义路由组件.png
⑤配置路由规则并创建路由实例对象
//创建路有实例
var router = new VueRouter({
//routes 路由规则数组
//每个规则至少包含path和component两个属性
//path是当前的路由规则匹配的hash地址
//component表示当前匹配的路由规则要展示的组件
routes: [
{ path: "/user", component: User },
{ path: "/register", component: Register },
],
});
⑥把路由挂在到vue根实例上去
image.png
2.2路由重定向
路由重定向.png
2.3路由嵌套
路由嵌套分析.png
代码示例:
//Register组件
const Register = {
template: `<div id="register">
<h1>Register组件</h1>
<hr/>
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<router-view></router-view>
</div>`,
};
//子路由组件
const tab1 = {
template: "<div>tab1组件</div>",
};
const tab2 = {
template: "<div>tab2组件</div>",
};
//创建路有实例
var router = new VueRouter({
//routes 路由规则数组
//每个规则至少包含path和component两个属性
//path是当前的路由规则匹配的hash地址
//component表示当前匹配的路由规则要展示的组件
routes: [
{ path: "/", redirect: "/user" },
{ path: "/user", component: User },
{
path: "/register",
component: Register,
//子路由规则,通过children属性为/register添加子路由规则
children: [
{ path: "/register", redirect: "/register/tab1" },
{ path: "/register/tab1", component: tab1 },
{ path: "/register/tab2", component: tab2 },
],
},
],
});
嵌套路由切换时存在组件复用的问题,不会多次执行钩子函数,可能会导致页面不再刷新,不会发起请求获取新的数据,
watch:{
$route:{
immediate:true,
deep:true,
handler(){
//处理逻辑
}
}
}
2.4动态路由匹配
场景思考:
2.4.1基本用法
动态路由匹配基本用法.png
2.5路由传参
路由组件参数传递布尔类型.png
路由组件参数传递对象类型.png
路由组件参数传递函数类型.png
2.6命名路由
命名路由.png
2.7编程式导航
query :path,name均可,相当于get,参数拼接在链接上
params:只能用name,相当于post
2.7.1基本用法
编程式导航.png
2.7.2 router.push参数
router.push参数.png
# [vue-router query和params传参(接收参数),route的区别 ]
2.8导航守卫
导航守卫全解析
先看一个钩子函数执行后输出的顺序截图吧,一般讲解都会在之后呈现,给大家换种思路(也就是先预习再学习最后复习)
image①全局守卫:
【全局的】:是指路由实例上直接操作的钩子函数,他的特点是所有路由配置的组件都会触发,直白点就是触发路由就会触发这些钩子函数,如下的写法。钩子函数按执行顺序包括beforeEach、beforeResolve(2.5+)、afterEach三个(以下的钩子函数都是按执行顺序讲解的):
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
[beforeEach]:在路由跳转前触发,参数包括to,from,next(参数会单独介绍)三个,这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。
[beforeResolve](2.5+):这个钩子和beforeEach类似,也是路由跳转前触发,参数也是to,from,next三个,和beforeEach区别官方解释为:
区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
即在 beforeEach 和 组件内beforeRouteEnter 之后,afterEach之前调用。
[afterEach]:和beforeEach相反,他是在路由跳转完成后触发,参数包括to,from没有了next(参数会单独介绍),他发生在beforeEach和beforeResolve之后,beforeRouteEnter(组件内守卫,后讲)之前。
②路由独享守卫:
【路由独享的】是指在单个路由配置的时候也可以设置的钩子函数,其位置就是下面示例中的位置,也就是像Foo这样的组件都存在这样的钩子函数。目前他只有一个钩子函数beforeEnter:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
[beforeEnter]:和beforeEach完全相同,如果都设置则在beforeEach之后紧随执行,参数to、from、next
③组件内路由守卫:
【组件内的】:是指在组件内执行的钩子函数,类似于组件内的生命周期,相当于为配置路由的组件添加的生命周期钩子函数。钩子函数按执行顺序包括beforeRouteEnter、beforeRouteUpdate (2.2+)、beforeRouteLeave三个,执行位置如下:
<template>
...
</template>
export default{
data(){
//...
},
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
<style>
...
</style>
[beforeRouteEnter]:路由进入之前调用,参数包括to,from,next。该钩子在全局守卫beforeEach和独享守卫beforeEnter之后,全局beforeResolve和全局afterEach之前调用,要注意的是该守卫内访问不到组件的实例,也就是this为undefined,也就是他在beforeCreate生命周期前触发。在这个钩子函数中,可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数,可以在这个守卫中请求服务端获取数据,当成功获取并能进入路由时,调用next并在回调中通过 vm访问组件实例进行赋值等操作,(next中函数的调用在mounted之后:为了确保能对组件实例的完整访问)。
beforeRouteEnter (to, from, next) {
// 这里还无法访问到组件实例,this === undefined
next( vm => {
// 通过 `vm` 访问组件实例
})
}
[beforeRouteUpdate] (v 2.2+):在当前路由改变时,并且该组件被复用时调用,可以通过this访问实例。参数包括to,from,next。可能有的同学会疑问,what is 路由改变 or what is 组件被复用?
对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,组件实例会被复用,该守卫会被调用
当前路由query变更时,该守卫会被调用
[beforeRouteLeave]:导航离开该组件的对应路由时调用,可以访问组件实例this,参数包括to,from,next。
至此,所有钩子函数介绍完毕。
屡一下哈:
全局路由钩子:beforeEach(to,from, next)、beforeResolve(to,from, next)、afterEach(to,from);
独享路由钩子:beforeEnter(to,from, next);
组件内路由钩子:beforeRouteEnter(to,from, next)、beforeRouteUpdate(to,from, next)、beforeRouteLeave(to,from, next)
不知道你是否还记得to、from、next这三个参数
下面请重头把这几个钩子函数的参数看一遍,细心的同学可以看见在afterEach钩子中参数没有next,为什么呢?
导航守卫回调参数:
to:目标路由对象;
from:即将要离开的路由对象;
next:他是最重要的一个参数,他相当于佛珠的线,把一个一个珠子逐个串起来。以下注意点务必牢记:
1.但凡涉及到有next参数的钩子,必须调用next() 才能继续往下执行下一个钩子,否则路由跳转等会停止。
2.如果要中断当前的导航要调用next(false)。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from
路由对应的地址。(主要用于登录验证不通过的处理)
3.当然next可以这样使用,next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。意思是当前的导航被中断,然后进行一个新的导航。可传递的参数与router.push中选项一致。
4.在beforeRouteEnter钩子中next((vm)=>{})内接收的回调函数参数为当前组件的实例vm,这个回调函数在生命周期mounted之后调用,也就是,他是所有导航守卫和生命周期函数最后执行的那个钩子。
5.next(error): (v2.4.0+) 如果传入 next
的参数是一个 Error
实例,则导航会被终止且该错误会被传递给 [router.onError()](https://link.zhihu.com/?target=https%3A//router.vuejs.org/zh-cn/api/router-instance.html%23%25E6%2596%25B9%25E6%25B3%2595)
注册过的回调。
总结:
好了,还记得那个截图吗,我们再看一遍
我们最后屡一下顺序:
当点击切换路由时:beforeRouterLeave-->beforeEach-->beforeEnter-->beforeRouteEnter-->beforeResolve-->afterEach-->beforeCreate-->created-->beforeMount-->mounted-->beforeRouteEnter的next的回调
当路由更新时:beforeRouteUpdate
三类:
①全局守卫:
beforeEach
②路由守卫:
beforeEnter
③组件守卫
beforeRouterEnter
beforeRouterUpdate
beforeRouterLeave
网友评论