1

走在前端的大道上

本篇将自己读过的相关 vue router 文章中,对自己有启发的章节片段总结在这(会对原文进行删改),会不断丰富提炼总结更新。

文章内容 基于vue 2.0

1.vue router如何传参?

1.1 params、query是什么?

params:/router1/:id ,/router1/123,/router1/789 //这里的id叫做params
query:/router1?id=123 ,/router1?id=456 //这里的id叫做query。
比如:跳转/router1/:id
<router-link :to="{ name:'router1',params: { id: status}}" >正确</router-link>
<router-link :to="{ name:'router1',params: { id2: status}}">错误</router-link>

1.2 html标签传参

params、query不设置也可以传参,params不设置的时候,刷新页面或者返回参数会丢失

路由界面:

当你使用params方法传参的时候,要在url后面加参数名,并在传参的时候,参数名要跟url后面设置的参数名对应。params是路由的一部分,必须要有,否则会导致跳转失败或者页面会没有内容
如图片 :id

clipboard.png

clipboard.png

// 上面的router-link传参,也可以使用编程式导航跳转
this.$router.push({  name:'router1',params: { id: status ,id2: status3},query: { queryId:  status2 }});
//编程跳转写在一个函数里面,通过click等方法来触发

query,是拼接在url后面的参数,就没有这种限制,直接在跳转里面用就可以,没有也没关系。

使用路由上面的参数

<template>
  <div class="router1">
    <h1>接收参数的路由</h1>
    <h1> params.id:{{ $route.params }}</h1>
    <h1>query.status:{{ $route.query.queryId }}</h1>
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

注意:获取路由上面的参数,用的是$route,后面没有r

本节参考文章:vue router 使用params query传参,以及有什么区别

1.3 vue this.$router.push()传参

params 传参
注意⚠️:patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据

this.$router.push({name: 'dispatch', params: {paicheNo: obj.paicheNo}})

取数据:

this.$route.params.paicheNo

query 传参

this.$router.push({path: '/transport/dispatch', query: {paicheNo: obj.paicheNo}})

取数据:

this.$route.query.paicheNo

2.this.$router 与 this.$route 

在登录页完成登录请求后进行下面的操作 获取路径中存放前一个路径的参数 ,然后跳转到该页面

 loginSuccess() {
      const { params: { back } } = this.$route;
      const route = back || { name: 'home' };
      const { name, params, query } = route;
      this.$router.replace({ name, params, query });
    },

在上面这段代码中出现了两个我们经常混淆的概念:
我们知道this.$routerrouter实例,可以用来直接访问路由。我们称router配置中每一个对象为一个路由记录,this.$route是暴露出来用来访问每个路由记录的。因此我们获取参数时使用的是this.$route 跳转路由时使用的是道this.$router

this.$router.push 与 this.$router.replace

上端代码中我们使用了replace而不是push来跳转路由,这两者的区别是会不会在history中产生记录。replace不会新增记录,而是直接替换掉了这条路由记录。

本节参考文章:vue router+ vuex+ 首页登录判断逻辑

3.路由懒加载

路由懒加载应该是写大一点的项目都会用的一个功能,只有在使用这个component的时候才会加载这个相应的组件,这样写大大减少了初始页面 js 的大小并且能更好的利用游览器的缓存。

首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):

const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
const Foo = resolve => require(['./Foo.vue'], resolve)
//或者
const Foo = () => import('./Foo');

官网:详细

4.单页及多页应用全局配置404页面

4.1 SPA的404路由配置

单页应用配置404页面,也区分两种情况:

4.1.1 路由表固定的情况

如果SPA的路由表是固定的,那么配置404页面就变得非常的简单。只需要在路由表中添加一个路径为404的路由,同时在路由表的最底部配置一个路径为*的路由,重定向至404路由即可。
(由于路由表是由上至下匹配的,一定要将任意匹配规则至于最底部,否则至于此路由规则下的路由将全部跳转至404,无法正确匹配。)

// router.js
export default new Router({
  mode: 'history',
  routes: [
    // ...
    {
      name: '404',
      path: '/404',
      component: () => import('@/views/notFound.vue')
    },
    {
      path: '*',    // 此处需特别注意至于最底部
      redirect: '/404'
    }
  ],
})
4.1.2 路由表动态生成的情况

路由表是动态生成的情况下,也就是说路由表分为两部分,一部分为基础路由表,另一部分是需要根据用户的权限信息动态生成的路由表。

本项目中动态生成路由采用vue-router自带的addRoutes方法,该方法是会将新的路由规则在原路由表数组的尾部注入的。由于任意匹配重定向至404页面的规则必须至于路由表的最底部,所以此处我将重定向至404页面的规则抽出,在动态路由注入后,再注入重定向规则,以确保该规则至于路由表最底部。

// router.js
export default new Router({
  mode: 'history',
  routes: [
    // ...
    {
      name: '404',
      path: '/404',
      component: () => import('@/views/notFound.vue')
    },
    // ...other codes
  ],
})
// notFoundRouterMap.js

export default [
  {
    name: '404',
    path: '/404',
    component: () => import('@/views/notFound.vue')
    },
  },
  {
    path: '*',
    redirect: '/404'
  }
]
// main.js

//...other codes
router.beforeEach((to, from, next) => {
  new Promise((resolve, reject) => {
    if (getCookie(tokenName)) {
      if (!getInfo()) {
        Promise.all([store.dispatch('getBasicInfo'), store.dispatch('getUserDetail')]).then(res => {
          store.dispatch('GenerateRoutes', { roles }).then(() => { 
          // 根据用户权限生成可访问的路由表
            router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
            router.addRoutes(NotFoundRouterMap) // 添加404及重定向路由规则
            resolve({ ...to, replace: true }) // 重新加载一次路由,让路由表更新成功后走下面else的判断
          })
          
        })
      } else {
        // ...other codes
      }
    } else {
      window.location.href = '/login.html'
    }
  }).then(res => {
    if (res) {
      next(res)
    } else {
      next()
    }
  }).catch(err => {
    new Error(err)
    next(false)
  })

4.2 多页应用的404路由配置

多页应用区别于SPA的不同点是每个页面有自己的一套路由,并且每个页面可能有自己的一套404页面风格,当然也可能没有。这时候,就不能再采用动态添加路由规则的方法了。

我采用的方案是在全局导航守卫beforeEach中对路由匹配的情况进行判断,这时候就需要用到vue导航守卫中的matched数组了。如果没有一个匹配上的,那么就重定向至404页面。当然,这个404页面也单独设置为一个页面。

// permission.js

//...other codes
router.beforeEach((to, from, next) => {
  new Promise((resolve, reject) => {
    // ...other codes
  }).then(res => {
    if (!to.matched.length) {
        window.location = '/error.html#/404'
        return
      } 
    if (res) {
      next(res)
    } else {
      next()
    }
  }).catch(err => {
    new Error(err)
    next(false)
  })

本节参考文章:Vue单页及多页应用全局配置404页面实践

5.后台系统权限控制

具体实现思路

  1. 创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
  2. 当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
  3. 调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
  4. 使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。

6.基于路由的动态过渡

<!-- 使用动态的 transition name -->
<transition :name="transitionName">
  <router-view></router-view>
</transition>
// 接着在父组件内
// watch $route 决定使用哪种过渡
watch: {
  '$route' (to, from) {
    const toDepth = to.path.split('/').length
    const fromDepth = from.path.split('/').length
    this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
  }
}

动手理解导航守卫(Vue)

Vue动态路由的实现(后台传递路由,前端拿到并生成侧边栏)

手摸手,带你用vue撸后台 系列二(登录权限篇)

vue router原理

前端的路由模式包括了 Hash 模式和 History 模式。
vue-router 在初始化的时候,会根据 mode 来判断使用不同的路由模式,从而 new 出了不同的对象实例。例如 history 模式就用 HTML5Historyhash 模式就用 HashHistory

vue-router 源码:前端路由
vue-router 源码:路由模式


于梦中2010
2.1k 声望181 粉丝

前端菜鸟儿,请多关照!