【Vue2】路由相关的知识点汇总

一、路由的跳转(路由的跳转就两种形式):

  1. 声明式导航(router-link:务必要有to属性)
  2. 编程式导航$router.push||replace

编程式导航更好用,以下只讨论编程式导航

  1. 优点:因为可以书写自己的业务逻辑,更加灵活
  2. 缺点:
    编程式导航路由跳转到当前路由(参数不变), 多次执行会抛出NavigationDuplicated的警告错误?
    注意:编程式导航(push|replace)才会有这种情况的异常,声明式导航是没有这种问题,因为声明式导航内部已经解决这种问题。这种异常,对于程序没有任何影响的。

为什么会出现这种现象:
由于vue-router引入了promise,当传递参数多次且重复,会抛出异常,因此出现上面现象,
下面代码重写:是给push函数,传递相应的成功的回调与失败的回调

重写VueRouter原型对象的push和replace方法

// 先把VueRouter原型对象的方法,保存一份
let originPush = VueRouter.prototype.push
let originReplace = VueRouter.prototype.replace

// 重写push|replace方法,
// 第一个参数:需要跳转的地址(传递那些参数),
// 第二个参数:成功的回调,
// 第三个参数:失败的回调
// 这里使用call||apply都可以修改函数的this指向,注意call传递参数用逗号隔开,apply传递参数用数组
VueRouter.prototype.push = function(location,resolve,reject){
    if(resolve && reject){
        originPush.call(this,location,resolve,reject)
    }else{
        originPush.call(this,location,()=>{},()=>{})
    }
}
VueRouter.prototype.replace = function(location,resolve,reject){
    if(resolve && reject){
        originReplace.call(this,location,resolve,reject)
    }else{
        originReplace.call(this,location,()=>{},()=>{})
    }
}



二、路由组件(页面)与非路由组件(组件)

  1. 路由组件通常存放在 pages || views 文件夹,一般组件(非路由组件)通常存放在components文件夹。
  2. 2路由组件一般需要在router文件夹中进行注册(使用的即为组件的名字),非路由组件在使用的时候,一般都是以标签的形式使用
  3. 通过切换,‘隐藏’了的路由组件,默认是被销毁掉的,需要的时候再去挂载
  4. 每个组件都有组件的$route属性,里面存储着组件的路由消息。
  5. 整个应用只有一个router,可以通过组件的$router属性获取到



三、两个重要的属性$router和$route

  1. $router:路由器对象

    router是挂载在根组件上的对象,这是一个全局的对象

    <!--在组件中可以通过this.$router来获取路由器对象。-->
    this.$router.push(path)       相当于点击<router-link>标签  还可以返回之前的路由
    this.$router.replace(path)    用新的路由,把老的路由替换掉,不可以返回之前的路由
    this.$router.back(); 返回上一个路由
    this.$router.forward(); 返回下一个路由
    this.$router.go(-1); 返回上一个路由
    this.$router.go(-2); 返回上两个路由
    this.$router.go(1);  返回下一个路由
    this.$router.go(2);  返回下两个路由
  1. $route:当前路由信息
    route是某一个跳转后的路由对象,是一个局部的对象
    <!--在组件中可以通过this.$route来获取路由对象。-->
   *this.$route.path       string,获取路由的url
   *this.$route.params     object,获取通过params传递的参数
   *this.$route.query      object,获取通过查询字符串传递的参数
   *this.$route.name       string,获取路由配置中的name
   *this.$route.meta       object,获取当前路由元信息
    this.$route.fullPath   string,完成解析后的 URL,包含查询参数和 hash 的完整路径。
    this.$route.matched    array,一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。
    this.$route.hash       当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。



四、路由传参(区分大小写)

  1. params参数: 路由中需要占位,使用params传参只能用name来引入路由(不能使用path)
  2. query参数: 路由不需要占位,使用query传参不限制name或者path引入路由
  3. 路由组件props:参数复杂起来,起到过滤参数的作用

1.params和query传参

路由配置信息

    {    
        name:'search',  //命名路由,编程式路由使用params传参时必须要使用命名路由
        path:'/search/:keyword?',    //在占位符后面写上一个?来表明可传可不传
        component:()=>import('@/pages/Search'),
        meta:{showFooter:true},
    },

路由跳转传参

    toSearch(){
        // 编程式路由导航中,对象写法中如果写了params参数配置项中不能写path必须写name(必须提前给url配置name属性),如果写了path则会忽略params
        <!-- 对象形式,query参数写法 -->
        this.$router.push({
            name:'search',  // 使用params参数不允许使用path引入路由
            // 对应的路由文件中,path:'/search/:keyword?', ,params传参需要提前在路由url中使用:占位符
            // 在占位符后面写上一个?来表明可传可不传
            params:{searchWord : a}   
        })
        
        <!-- 对象形式,query参数写法 -->
        this.$router.push({
            // name:'search', 
            path:'search',  // query参数不限制使用name或path引入路由
            query:{searchWord: b}
        })
    }

使用params参数,页面url不显示参数名称 http://localhost:8080/search/a

获取params参数 this.$route.params.searchWord

使用query参数,页面url显示 http://localhost:8080/search?searchWord=b

获取query参数 this.$route.query.searchWord

2.路由组件props传参

当参数变为复杂,为了更方便的接收参数(起到解耦的作用)。和props配置项一样需要在组件实例身上通过props:['a','b']接收使用。即跳转组件类似形成父子关系进行props传参。

  1. 布尔模式

    如果 props 被设置为 true,route.params所有参数通过props传递给组件。

  2. 对象模式

    如果 props 是一个对象,该对象以键值对的组合通过props传递给组件。当 props 是静态的时候有用。

  3. 函数模式

    你可以创建一个函数返回 props。函数返回的对象以键值对通过props传递给组件,可以params参数、query参数、通过props传递给路由组件。

    {
      path:'message', 
      component:Message,
      children:[
          {
              name:'xiangqing',
              path:'detail',  //二级路由不能加路径
              component:Detail,
    
              // props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件
              props:{a:1,b:'hello'},
              // props的第二种写法,值为对象,若布尔值为真,就会把路由组件收到的所有params参数,以props的形式传给Detail组件
              props:true,
              // props的第三种写法,值为函数,此写法最强大,此处可以解构赋值并连续解构赋值
              props($route){
                  return {
                      id:$route.query.id,
                      title:$route.query.title
                  }
              }
          }
      ]
    },



五、路由的嵌套

配置路由规则,使用children配置项

    // 创建并暴露一个路由器
    export default new VueRouter({
        routes:[
            {
                path:'/about',
                component:About
            },
            {
                name: 'center',
                path: '/center',
                component: () => import('@/pages/Center'),
                meta: { showFooter: true },
                // 二级路由组件
                children: [
                    {
                        path: 'myorder',     //二级路由不能加路径/
                        component: () => import('@/pages/Center/MyOrder'),
                    },
                    {
                        path: 'grouporder',     //二级路由不能加路径/
                        component: () => import('@/pages/Center/GroupOrder'),
                    },
                    {
                        path: '/center',      //重定向的时候需要加路径/
                        redirect: '/center/myorder'
                    }
                ]
            }
        ]
    })



六、路由元信息meta

路由元信息可以当做一个开关,在路由配置信息中控制控制显示、隐藏 和 登录校验、权限控制。

  1. 通过路由元meta和v-show来控制组件的显示与隐藏

    <Footer v-show="$route.meta.showFooter"></Footer>

    {
        name: 'home',
        path: '/home',
        component: () => import('@/pages/Home'),
        meta: { showFooter: true }      // 路由元控制显示
    },
    {
        name: 'login',
        path: '/login',
        component: () => import('@/pages/Login'),
        meta: { showFooter: false }      // 路由元控制隐藏
    }
  1. 通过路由元meta和beforeEach导航守卫来控制路由权限,登录校验
// 路由页配置页面
    {
      path: '/normal',
      name: 'Normal',
      component: Normal,
      meta: {login_require: false},     // 路由元 登录许可:false 不需要登录许可
    },
    {
      path: '/vip',
      name: 'Vip',
      component: Vip,
      meta: {login_require: true}     // 路由元 登录许可:true 需要登录许可
    }
// 路由器页面,全局前置守卫控制登录跳转
    router.beforeEach((to, from, next) => {
        // some找出当前嵌套路径数组中的路由元信息是否包含登录许可
      if (to.matched.some(function (item) {     // matched为一个数组,当前所有嵌套路径数据
        return item.meta.login_require
      })) {
        next('/login')      // 若发现登录许可为true,则调整登录页面
      } else 
        next()      // 若发现登录许可为false,则放行
    })



七、路由懒加载

路由懒加载无需额外引入路由组件,当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

    {
        name: 'home',
        path: '/home',
        component: () => import('@/pages/Home'),    // 路由懒加载
        meta: { showFooter: true }      // 路由元
    },



八、 缓存路由组件

  1. 作用:正常切换组件,组件会销毁。缓存路由让不展示的路由组件保持挂载,不被销毁
  2. 具体编码:
 <!-- keepalive 缓存多个,:include 必须写组件名.,并且包在router-view外 -->
  <keep-alive :include="['News', 'Message']">
    <router-view></router-view>
  </keep-alive>
  
  <!-- 缓存一个路由组件 -->
  <keep-alive include="News">
    <router-view></router-view>
  </keep-alive>

路由组件中的两个新的生命周期钩子

router-view组件,如果被包裹在keep-alive里面,所以路径匹配的组件都会被缓存。

如果使用keep-alive组件将会多出两个钩子函数分别为 activated 和 deactivated。

  1. 作用:路由组件多出两个钩子,用于捕获路由组件的激活状态。
  2. 具体名字:
    1. actived 路由组件被激活时触发
    2. deactived 路由组件失活时触发

一个使用过的生命周期钩子,把真实的dom放入页面后,在调用nextTick函数
$nextTick(){}

组件的缓存问题

  1. 组件的缓存可以提升用户的体验

    比如:登录输入的时候,当切换其他路由再切回来时,还是保留着之前的输入数据。

  2. 组件的缓存与ajax发送请求带来的冲突问题

    一个组件的数据需要实时跟后台数据同步,如果被keep-alive缓存可能就不会发送ajax请求,这样也就导致不会实时的获取最新的数据

  3. keep-alive包裹着的router-view组件位置的所有组件都会被缓存

  4. 有的组件不想被缓存就需要keep-alive的重要属性去处理

keep-alive重要的两个属性

  1. include字符串或正则表达式,只有匹配的组件会被缓存。

  2. exclude字符串或正则表达式,任何匹配成功的组件都不会被缓存,用的比较多




九、路由工作模式

路由器的两种工作模式

  1. 对于一个url来说,什么是hash值---#及其后面的内容就是hash值
  2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器。
  3. hash模式:
    1. 地址中永远带着#号,不美观
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
    3. 兼容性较好
  4. history模式:
    1.地址干净、美观
    2.兼容性和hash模式相比略差
    3.应用部署上线时需要后端人员支持,解决刷新页面服务端4040的问题。



十、路由守卫

站内跳转路由守卫文章。

posted @ 2022-05-22 23:51  wanglei1900  阅读(139)  评论(0编辑  收藏  举报