vue系列之动态路由详解【原创】

开题

最近用vue来构建了一个小项目,由于项目是以iframe的形式嵌套在别的项目中的,所以对于登录的验证就比较的麻烦,索性后端大佬们基于现在的问题提出了解决的方案,在看到他们的解决方案之前,我先画了一个比较标准的单系统的解决方案。

本文目录:

一: 设想
二: 讨论
三:实现
四:总结

一: 设想

简单解释下上图就是:

首先前端从cookie获取token,如果没有token就跳转到登录页面登录,登录验证之后生成token存在数据库中并返回给前端;前端将这个token保存下来,为了让在浏览器新的tab页时不需要登录,我们前端需要将这个token保存到cookie之中。

如果用户已经有了token,那么再验证是否有用户信息,如果没有去请求用户信息的接口,后台读取用户的基本信息返回给前端,前端根据后台返回的用户权限生成固定的路由表用于页面拦截。

在用户token和权限都有的情况下,进入自己权限内的页面并且携带token访问后台进行交互。

用户在退出时,请求后台接口,清除token数据。

二: 讨论

由于公司的项目更加的复杂,属于基于原来的系统开发新的系统模块,但是这些模块又为了以后主体功能的更新下次迭代需要保持相对的独立性,预计以后的老系统只起一个用户中心的功能,所以现在是基于实现单点登录的能力去迭代更新现在的新的项目。

今天上午对于登录的实现进行了相关讨论,由于公司项目保密考虑只是单单做相关的介绍:

现有的老项目将慢慢向用户中心转换,而以前的新项目需要去这个用户中心获取登录信息。具体的实现是:

登录新项目b.exaplem.com通过session检测到未登录时(这里说下新的项目和老项目在同一个一级域名下),跳转到a.exaplem.com?returnUrl='b.exaplem.com',在a.exaplem.com下成功登录后生成一个ticket给到b.exaplem.com,b.exaplem.com将这个ticket存在session里面来保持登录状态。

因为现在基本上是先登录a.exaplem.com然后再去登录b.exaplem.com,所以当我们第一次进入b.exaplem.com系统时,b.exaplem.com会向a.exaplem.com系统发送请求来获取ticket,并且生成session来维持登录状态。

三:实现

当时想通过引入vuex并通过cookie来保存token的状态,但是由于现在的项目还是后端以session的形式来维持用户的登录状态所以还是没有引入vuex。

基本实现如下:

main.js增加引入的permission.js文件如下:

import Vue from 'vue'
import router from './router'
import { asyncRouterMap, constantRouterMap } from './router'

function hasPermission(roles, route) { //
 if (route.meta && route.meta.role) {
  return roles.some(role => role === route.meta.role)
 } else {
  return true
 }
}

function filterAsyncRouter(asyncRouterMap, roles) {

 const accessedRouters = asyncRouterMap.filter(route => {
  if (hasPermission(roles, route)) {
   if (route.children && route.children.length) {
    route.children = filterAsyncRouter(route.children, roles)
   }
   return true
  }
  return false
 })

 return accessedRouters
}

// 加载页面之前
router.beforeEach((to, from, next) => {
 NProgress.start() // 开启Progress
 if (to.path == '/ContractAduit/Error') {
  next()
 } else if (!Vue.prototype.hasRoute) {

  Vue.prototype.$ajax.get(Vue.prototype.$api.getModuleHost("用户信息接口地址"), {})
   .then(data => {
    if (data.code == 1000) {
     let menus = data.menu
     let roles = menus.map((menu, index) => {
      return parseInt(menu.url);
     })
     const accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
     router.addRoutes(accessedRouters)
     Vue.prototype.userInfo = {
      id: data.id,
      realname: data.realname
     }
     Vue.prototype.hasRoute = true;
     next({...to })
    } else {
     router.push({ name: 'ErrorPageRouter' });
    }
   })
   .catch(err => console.log(err))
 } else {
  next()
 }
});

route.js文件如下:

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export const constantRouterMap = [{
  path: '/404',
  name: 'NoFoundPagetRouter',
  component: require('../views/404.page'),
  meta: {
   title: '404',
  }
 },
 {
  path: '/ContractAduit/NoAccess',
  name: 'NoAccessPageRouter',
  component: require('../views/no-access.page'),
  meta: {
   title: '无权限',
  }
 },
 {
  path: '/ContractAduit/Error',
  name: 'ErrorPageRouter',
  component: require('../views/error.page'),
  meta: {
   title: '内部错误',
  }
 }
]

export default new Router({
 mode: 'history',
 routes: constantRouterMap
})

export const asyncRouterMap = [{
  path: '/ContractAduit/Supplier/List',
  name: 'SupplierListPageRouter',
  component: require('../views/supplier/supplier-list.page.vue'),
  meta: {
   title: '某某列表页',
   role: 10001
  }
 },
 ...
 {
  path: '/',
  redirect: '/ContractAduit/Supplier/List',
  hidden: true,
  meta: {
   title: '某某列表页',
   role: 10001
  }
 }, {
  path: '*',
  redirect: '/404',
  hidden: true
 }
]

因为没有引入vuex所以需要在VUE构造函数的原型对象上声明变量来判断是否已经拉取了用户的基本信息,因为我们后端的权限是配置的页面级权限(即不是按照角色来安排哪个前端页面来可访问,而是根据后台返回的页面代码来判断哪个前端页面可访问)。

四:总结

因为我们的项目不可能达到千篇一律的情况,选择适合自己项目的解决方案才是最重要的,不要为了用某个技术而去用某个技术。

以上这篇vue系列之动态路由详解【原创】就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 详解vue-router2.0动态路由获取参数

    一下demo演示2.0中的vue-router是如何获取到不同参数的,并在地址栏中匹配不同的信息 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="vue.js&qu

  • vue动态路由实现多级嵌套面包屑的思路与方法

    前言 最近在工作中遇到了一个问题,是关于vue动态路由多级嵌套面包屑怎么弄(不是动态路由嵌套可以尝试用 this.$route.matched方法获取到path和name集合,动态的嵌套获取不到全部具体的id) 功能比如:A列表页面路由如/a,点击任意一列进入任意一个A的详情页面名字为B,/b/03(这个是动态路由弄是吧,03就是id嘛),点击B页面任意一列,再进入B的详情页名字为C,路由如/bdetail/01;现在弄面包屑要获取到的路由是刚刚打开的,如(/a:/b/03:/bdetail/0

  • vue用addRoutes实现动态路由的示例

    之前在基于Vue实现后台系统权限控制一文中提到路由权限的实现思路,因为不喜欢在每次路由跳转的before钩子里做判断,所以在初始化Vue实例前对路由做了筛选,再用实际路由初始化Vue实例,代价是登录页需要从Vue实例中独立出来,实现上倒没什么问题,不过这种做法需要在登录和首页之间通过url跳转,感觉总是不太"优雅",实际上只要能在登录后动态修改当前实例的路由就行了,之前确实没办法,但vue-router 2.2版本新增了一个router.addRoutes(routes)方法,让动态路

  • vue系列之动态路由详解【原创】

    开题 最近用vue来构建了一个小项目,由于项目是以iframe的形式嵌套在别的项目中的,所以对于登录的验证就比较的麻烦,索性后端大佬们基于现在的问题提出了解决的方案,在看到他们的解决方案之前,我先画了一个比较标准的单系统的解决方案. 本文目录: 一: 设想 二: 讨论 三:实现 四:总结 一: 设想 简单解释下上图就是: 首先前端从cookie获取token,如果没有token就跳转到登录页面登录,登录验证之后生成token存在数据库中并返回给前端:前端将这个token保存下来,为了让在浏览器新

  • VUE+elementui面包屑实现动态路由详解

    我的路由: const routerMap = [ { path: '/', redirect: 'dashboard', component: Layout, name:'Dashboard', children: [ { path: 'dashboard', component: () => import('@/view/dashboard'), name: 'Dashboard', meta: { title: 'dashboard', icon: 'dashboard', noCache

  • Vue 使用Props属性实现父子组件的动态传值详解

    如下所示: <!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue&quo

  • vue.js 动态组件详解

    :is 动态组件 使用 v-bind:is="组件名",会自动去找匹配的组件名,如果没有,则不显示: <div id="app"> <test v-bind:is="which_to_show"></test> </div> <script> var demo = new Vue({ el: "#app", data: { which_to_show: "f

  • vue iview实现动态路由和权限验证功能

    github上关于vue动态添加路由的例子很多,本项目参考了部分项目后,在iview框架基础上完成了动态路由的动态添加和菜单刷新.为了帮助其他需要的朋友,现分享出实现逻辑,欢迎一起交流学习. Github地址 iview-dynamicRouter 实现目标 客户端从服务端拿到路由和权限数据后,刷新项目的路由和菜单列表,并进行权限控制. 项目基础 基础框架: iview组件库官方模板项目 iview-admin 的template分支项目,此项目为 iview-admin 的基础框架代码.项目地

  • 关于vue里页面的缓存详解

    keep-alive是vue内置的一个组件,可以使被它包含的组件处于保留状态,或避免被重新渲染. 用法: 运行结果描述: input输入框内,路由切换输入框内部的内容不会发生改变. 在keep-alive标签内部添加 include:字符串或正则表达式.只有匹配的组件会被缓存 exclude: 字符串或正则表达式.任何匹配的组件都不会被缓存. 结合router缓存部分页面: 比较实用的例子: 思路:通过beforeRouterLeave这个钩子来对路由里面的keepAlive进行赋值.从而动态的

  • vue前端开发keepAlive使用详解

    目录 前言 keep-avlive钩子函数 keep-avlive缓存哪些组件 小结及注意事项 前言 keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们. 在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性.使用方式为 <keep-alive> <component /> </keep-alive> 这里的component会被缓存. keep-avlive钩子函数 被包含

  • Vue的Props实例配置详解

    目录 1.Prop 的大小写 2.Prop 类型 3.Prop验证 4.传递静态|动态 Prop 5.修改Prop数据 适用于:父子组件通信. 如果父组件给子组件传递(函数)数据:本质是子组件给父组件传递数据: 如果父组件给子组件传递的(非函数)数据:本质就是父组件给子组件传递数据. 路由组件也可以传递 props数据. 1.Prop 的大小写 HTML 中的 属性名大小写不敏感,浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的

  • Vue组件选项props实例详解

    前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息.本文将详细介绍Vue组件选项props 静态props 组件实例的作用域是孤立的.这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据.要让子组件使用父组件的数据,需要通过子组件的 props 选项 使用Prop传递数据

  • vue项目中axios使用详解

    axios在项目中(vue)的使用 没有vue项目的使用vue-cli脚手架生成一个webpack模板的项目即可愉快的看下去了~ 如果开发遇到跨域问题可以参考:http://www.jb51.net/article/134571.htm 安装axios到项目中 npm install axios --save 配置wepack别名,不同环境访问不同的配置接口 配置: 使用:import config from 'config' 封装一个axios实例 新建fetch.js,在此创建axios实例

随机推荐