撸一个基于VUE的WEB管理后台(五)

api server已经有一个最基本的框架了,我们回到前端,开始制作一个用户管理界面吧。

路由管理与Layout

从main.js可以看到渲染的入口是App.vue

import App from './App'
new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})

App.vue里的模板很简单,就是一个router-view

<template>
  <div id="app">
    <router-view />
  </div>
</template>

结合之前分析过的permission.js,中间有个白名单:

const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist

如果是未登录用户(判断依据就是store中没有token),访问的url又不在这个白名单中,就强行跳转到login页面

  next(`/login?redirect=${to.path}`)

对于已经登录过,但store中还没有用户角色信息的情况,先调用info接口获取角色信息,根据添加动态路由配置,最后在将页面路由到指定的url

  const { roles } = await store.dispatch('user/getInfo')
  const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
  router.addRoutes(accessRoutes)
  next({ ...to, replace: true })

现在我们知道前端的路由配置都是在store/permission.js中的generateRoutes中实现的,查看相关代码,generateRoutes会根据用户角色生成对应的动态路由规则,最后将这些规则与constantRoutes中定义的静态规则合并到一起。

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

constantRoutes和asyncRoutes都是在router/index.js中定义的,router组件也是在这里初始化的,可以看出,初始化时只配置了静态规则:

const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({
    y: 0
  }),
  routes: constantRoutes
})

const router = createRouter()

constantRoutes静态规则是一个大的数组,包含了url和对应view组建的映射关系

export const constantRoutes = [{
    path: '/redirect',
    component: Layout,
    hidden: true,
    children: [{
      path: '/redirect/:path*',
      component: () => import('@/views/redirect/index')
    }]
  },
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

asyncRoutes也是类似的数组,只不过额外增加了一些访问控制信息

export const asyncRoutes = [
    path: '/permission',
    component: Layout,
    redirect: '/permission/page',
    alwaysShow: true, // will always show the root menu
    name: 'Permission',
    meta: {
      title: 'permission',
      icon: 'lock',
      roles: ['admin', 'editor'] // you can set roles in root nav
    },
    children: [{
        path: 'page',

大概了解一下前端路由生成机制,我们发现几乎所有路由都指向了Layout组件,继续查看Layout源码layout/index.vue,这个组件是整个页面布局的入口,左边的siderbar,顶部的navbar,内容区的app-main,以及右边的浮动设置按钮right-panel。

<template>
  <div :class="classObj" class="app-wrapper">
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
    <sidebar class="sidebar-container" />
    <div :class="{hasTagsView:needTagsView}" class="main-container">
      <div :class="{'fixed-header':fixedHeader}">
        <navbar />
        <tags-view v-if="needTagsView" />
      </div>
      <app-main />
      <right-panel v-if="showSettings">
        <settings />
      </right-panel>
    </div>
  </div>
</template>

跟进看一下layout/components/AppMain.vue的实现,发现他的html模板里又包含了一个router-view,这就能让我更好地理解嵌套路由的配置了。

<template>
  <section class="app-main">
    <transition name="fade-transform" mode="out-in">
      <keep-alive :include="cachedViews">
        <router-view :key="key" />
      </keep-alive>
    </transition>
  </section>

在这里插入图片描述
了解Layout的结构,就可以知道,layout/components/siderbar/会根据路由规则实现siderbar中的菜单项,layout/components/Navbar实现了navbar,至于app-main,根据各项路由的component参数可知,一般都放在views/目录下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值