美文网首页前端学习Vue项目构建
项目经验 | Vue+webpack4的项目总结

项目经验 | Vue+webpack4的项目总结

作者: 格致匠心 | 来源:发表于2019-06-30 12:31 被阅读0次

    一、目录结构

    • assets放置了静态文件
    • components放置了通用组件
    • config放置了一些常量配置
    • helper放置了主要的功能模块比如ajax.js、api.js
    • mixins放置了混入
    • router放置了路由文件
    • store放置了vuex的文件
    • views放置了页面文件
    目录结构

    二、 鉴权

    项目的登陆状态由Vuex+LocalStorage维持,项目的鉴权主要靠 路由鉴权 和 Ajax鉴权。

    store结构

    store结构

    state,localStorage维持了登陆信息的持久化

    const state = {
      userInfo: $storage.getLocalStorage('userInfo') || {}
    }
    

    设置和删除userInfo的都放在mutation里

    import { $storage } from '@/helper'
    
    export default {
      setUserInfo (state, info) {
        state.userInfo = info
        $storage.setLocalStorage('userInfo', info)
      },
      deleteUserInfo (state) {
        state.userInfo = null
        $storage.removeLocalStorage('userInfo')
      }
    }
    

    向服务器获取userInfo放在action里(异步类型的)

    import { $apis } from '@/helper'
    export default {
      async getUserInfo ({ commit, state }) {
        let userId = state.userInfo.id
        if (userId) {
          $apis.getUserInfo(userId).then(res => {
            commit('setUserInfo', res)
          })
        }
      }
    }
    

    auth文件

    实际上router鉴定权限调用的都是这两个方法,把它们分离出一个文件,用来检查有没有userInfo和userInfo是否是Admin的权限。

    import { $apis, $storage } from '.'
    
    export default {
      checkSession () {
        return $storage.getLocalStorage('userInfo') || false
      },
    
      async checkAdmin () {
        let userInfo = $storage.getLocalStorage('userInfo') || {}
        let userId = userInfo.id || 0
        if (!userId) return false
        userInfo = userInfo || (await $apis.getUserInfo(userId))
        let isAdmin = userInfo.permission < 2
        return userInfo.id && isAdmin
      }
    }
    

    router结构

    router结构

    鉴权这里用的是全局前置守卫,所以在beforeEachHooks.js写上鉴定权限的规则。
    规则:在需要admin权限的地方无权限访问,则会跳到404页面;在需要登陆权限的地方无权限访问,则会跳到login界面。

    import { $auth } from '@/helper'
    export default {
      checkVisitAuth (to, from, next) {
        if (to.meta.isNeedAdmin) {
          $auth.checkAdmin().then(result => {
            return result ? next() : next({ path: '/404' })
          })
        } else if (to.meta.isNotNeedLogin) {
          next()
        } else {
          $auth.checkSession() ? next() : next({ path: '/login' })
        }
      }
    }
    

    在index.js处挂载该规则

    Object.values(beforeEachHooks).forEach(hook => {
      routerInstance.beforeEach(hook)
    })
    

    Ajax

    用了一层requestHandle来封装 axios,以后可能会改用interceptors来定制,比较符合通用的做法。
    后端返回 401 就是没有登陆或者登陆信息过期,这时候清空登陆缓存状态,然后重定向到登陆页面。
    后端返回 403 就是没有权限访问,由于本项目403也是跳到404页面所以和404同用一个处理方式。
    后端返回 415 是访问api过多被限制。

    /**
     * @param url
     * @param method get|post|put|delete...
     * @param params like queryString. if a url is index?a=1&b=2, params = {a: '1', b: '2'}
     * @param data post data, use for method put|post
     * @returns {Promise}
     */
    function requestHandle (url, method, options) {
      if (options !== undefined) {
        var { params = {}, data = {} } = options
      } else {
        options = {}
      }
      return new Promise((resolve, reject) => {
        axios({
          url,
          method,
          params,
          data
        })
          .then(
            res => {
              if (res.status === 200 || res.status === 201 || res.status === 204) {
                resolve(res.data)
              } else {
                reject(res)
              }
            },
            err => {
              if (err.response.status === 401) {
                store.commit('deleteUserInfo')
                Vue.prototype.$error('请登陆')
                window.location.href = '/login'
                reject(err)
              } else if (
                err.response.status === 403 ||
                err.response.status === 404
              ) {
                reject(err.response.data)
              } else if (err.response.status === 415) {
                Vue.prototype.$error('您访问太过频繁, 已被限速')
                reject(err.response.data)
              }
            }
          )
          .catch(err => {
            Vue.prototype.$error(err)
            reject(err)
          })
      })
    }
    

    总体结构

    实际上该项目的鉴权就是路由拦截那些正常的权限缺失,减少后端压力,而在登陆信息过期或者恶意修改登陆信息的会遭到后端的铁拳制裁😄,后端必须要有完整的鉴权系统才能是健壮的。

    相关文章

      网友评论

        本文标题:项目经验 | Vue+webpack4的项目总结

        本文链接:https://www.haomeiwen.com/subject/swgvcctx.html