美文网首页
Vue Router

Vue Router

作者: 我家有个王胖胖 | 来源:发表于2022-02-21 17:07 被阅读0次

一:路由的基本概念
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>

效果预览:

router.gif
二: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动态路由匹配
场景思考:

思考.png
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传参(接收参数),router,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) 注册过的回调。

总结:
好了,还记得那个截图吗,我们再看一遍

image

我们最后屡一下顺序:

当点击切换路由时:beforeRouterLeave-->beforeEach-->beforeEnter-->beforeRouteEnter-->beforeResolve-->afterEach-->beforeCreate-->created-->beforeMount-->mounted-->beforeRouteEnter的next的回调

当路由更新时:beforeRouteUpdate

三类:
①全局守卫:
beforeEach
②路由守卫:
beforeEnter
③组件守卫
beforeRouterEnter
beforeRouterUpdate
beforeRouterLeave

相关文章

网友评论

      本文标题:Vue Router

      本文链接:https://www.haomeiwen.com/subject/obfilrtx.html