7

导读:

很久没有写文章了,最近一直在忙,之前一直想着可以把SanJi Boot Security项目中的页面使用 Vue+webpack 进行重写,前几天算是阶段性的完成了这个计划,后期会随着SanJi Boot 的模块不断增多 对进行对应的升级与扩展

简介:

项目源码已托管到码云上

使用技术:

webpack + Vue + Vue Router + iviewUI

实现了什么功能:

基于token进行登陆时的认证 支持跨域 需要后台配合

修改 config/index.js 文件

const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: { '/api':
      {
        target:'http://localhost:8089/api',
        changeOrigin:true,
        pathRewrite:{
        '^/api': ''
        }
      }
    }
   ...
  }
}

自定义 axios src/api/http.js 文件

import router from '../router'
import axios from 'axios'
import bus from '../bus'


// axios 配置
axios.defaults.timeout = 30000;

axios.interceptors.request.use(
  config => {
    if (bus.state.token) {  // 判断是否存在token,如果存在的话,则每个http header都加上token
      config.headers.Authorization = `${bus.state.token}`;
    }
    return config;
  },
  err => {
    return Promise.reject(err);
  });

// http response 拦截器
axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 401:
          // 返回 401 清除token信息并跳转到登录页面
          bus.state.token=undefined;
          router.replace({
            path: 'login',
            query: {redirect: router.currentRoute.fullPath}
          })
      }
    }
    return Promise.reject(error.response.data)   // 返回接口返回的错误信息
  });
export default axios;

基于Vue Router 在进入页面前进行权限的前端认证

编写 src/router/index.js 文件

import Vue from 'vue'
import Router from 'vue-router'
import bus from '../bus'

Vue.use(Router)

//base

const Index = resolve => require(['../views/Index'], resolve)

const Login = resolve => require(['../views/Login'], resolve)

const Home = resolve => require(['../views/demo/Home'], resolve)

const Forbidden = resolve => require(['../views/demo/403'], resolve)

const NotFound = resolve => require(['../views/demo/NotFound'], resolve)

const Icon = resolve => require(['../views/demo/Icon'], resolve)

const Demo = resolve => require(['../views/demo/Demo'], resolve)

// sys

const UserManager = resolve => require(['../views/sys/User'], resolve)

const RoleManager = resolve => require(['../views/sys/Role'], resolve)



const router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      component: Login
    },
    {
      path: '/',
      name: 'index',
      component: Index,
      meta: {
        requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
      },
      children: [
        {
          path: '//',
          name: '首页',
          component: Home,
          meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
          },
        },
        {
          path: '/demo',
          name: 'demo',
          component: Demo,
          meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
          },
        }, {
          path: '/icon',
          name: 'icon',
          component: Icon,
          meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
          },
        },
        {
          path: '/sys/user',
          name: '用戶管理',
          component: UserManager,
          meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
            permissions:'sys-user'
          }
        },
        {
          path: '/sys/role',
          name: '角色管理',
          component: RoleManager,
          meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
            permissions:'sys-role'
          }
        },
        {
          path: '/403',
          name: '403',
          component: Forbidden,
        },{
          path: '/*',
          name: '404',
          component: NotFound,
          meta: {
            requireAuth: true,  // 添加该字段,表示进入这个路由是需要登录的
          }
        }
      ]
    }]
});

router.beforeEach((to, from, next) => {
  if (to.path === "/logout") {
    bus.state.token = undefined;
    next({
      path: '/login'
    })
  }else{
    bus.state.menu_title = to.name;
    if (to.meta.requireAuth) {  // 判断该路由是否需要登录权限
      // console.log('token:',bus.state.token!=null,bus.state.token,)
      if (bus.state.token!="undefined"&&bus.state.token) {  // 通过vuex state获取当前的token是否存在
        if(to.meta.permissions){
          if(bus.action.hasPermissions(bus,to.meta.permissions)){
            next();
          }else{
            bus.state.menu_title = '403'
            next('/403');
          }
        }else{
          next();
        }
      } else {
        next({
          path: '/login',
          query: {redirect: to.fullPath}  // 将跳转的路由path作为参数,登录成功后跳转到该路由
        })
      }
    } else {
      next();
    }
  }
})

export default router;

后台界面主框架 material design 风格

基于material_admin 实现前端界面响应式设计 支持快速切换后台界面主框架

  <Index :current_system="current_system" :system_list="system_list" :user="user" :user_menus="user_menus"
         :menus="menus" :menu_title="bus.state.menu_title"
         @click_sys_switch="sys_switch" @click_search="search" @open_tab="open_tab">
    <transition name="slide-left">
      <router-view></router-view>
    </transition>
  </Index>

目前有哪些功能模块:

用户管理
角色管理
demo表格+Icon图标

界面截图:

登陆页面
登陆页面
用户管理
用户管理
角色管理
角色管理
icon
ICON

后记

项目已托管 码云
需要配合 sanji-boot-security 使用

学习资料

快速上手 webpack+vue - vue cli 起手式


yangrd
1.3k 声望225 粉丝

代码改变世界,知行合一。