Vue+antd前端篇——项目构建+路由守卫+请求拦截+VUEX

前言

前几天和大家说要分享下前后端开发的经验,今天他来了!因为最近工作比较忙,内容也比较多需要分开几篇来讲,分享的内容不会有太深的理论东西,都是比较实用且简单易懂。作为第一篇分享先以前端开始,从项目创建到搭建基础架构,这块内容会比较多,所以会分开两篇或三篇,希望想学的朋友多些耐心哈,因为我也是抽时间一点点写,所以更新不会特别快,大概一周更新一到两篇吧,希望各位同学多多担待!

CODING...

第一步,我们首先需要安装下环境,具体就不阐述了,这里需要注意一个点就是构建项目时有个区别需要讲一下,大牛请忽略!

vue init 和 vue create的区别:

vue create 是vue-cli3.x的初始化方式,目前模板是固定的,模板选项可自由配置,创建出来的是vue-cli3的项目,与cue-cli2项目结构不同,配置方法不同,具体配置方法参考官方文档。vue init 是vue-cli2.x的初始化方式,可以使用github上面的一些模板来初始化项目,webpack是官方推荐的标准模板名。vue-cli2.x项目向3.x迁移只需要把static目录复制到public目录下,老项目的src目录覆盖3.x的src目录(如果修改了配置,可以查看文档,用cli3的方法进行配置)

我这里是构建的是cli2.x版本,所以项目中很多配置都是cil2.x的配置方式,请大家注意下!

第二步,构建完成后我们启动下项目(有问题请自行百度,这个比较基础了),先把没有用的东西给干掉,然后引入ant-design-vue框架,npm install ant-design-vue --save,然后引入样式文件,这里有问题的同学可以参考antd官网

Vue+antd前端篇——项目构建+路由守卫+请求拦截+VUEX_第1张图片

这里说一下,我是做的全局引入,没有做按需加载,我尝试了做按需加载有些问题,官网上找不到解决方案,需要自行百度,大概是JavaScriptEnabled的问题,如果做按需加载项目建议大家基于cli3.x进行搭建!

第三步,引入antd测试下没有问题的话我们开始配置路由守卫,我这里设置了一个丐版的,高配版大家根据自己需求调整就好

// 设置路由守卫,全局页面title修改
router.beforeEach((to, from, next) => {
  if (to.meta.title) {
    document.title = `VueDemo网站-${to.meta.title}`
  }
  const token = localStorage.getItem(ACCESS_TOKEN)
  if (token) {
      next()
  } else {
    if (to.meta.required) {
      next({path: '/login'})
    } else {
      next()
    }
  }
})

我这里简单设置了一下当路由包含required且为true需要登录,所以我称之为丐版,正常项目中可以去设置自己的白名单来引入控制,或是包括一些权限的控制都在路由守卫里来完成,这里我通过localstorage来获取token,也可以引入Vue-ls插件来代替localstorage。

第四步,设置请求拦截,我把拦截器定义在router文件下了,新建一个request.js文件,我用的是axios来做请求拦截,先创建一个实例

import axios from 'axios'
import store from '../store'
import notification from 'ant-design-vue/es/notification'
import { ACCESS_TOKEN } from '../store/mutation-type'
const service = axios.create({
  timeout: 6000
})

引入模块,然后定义请求和返回的响应机制,因为在请求接口之前先运行的就是拦截器,所以这里要写到位

// request发送请求配置
service.interceptors.request.use(config => {
  const token = localStorage.getItem(ACCESS_TOKEN)
  if (config.url.indexOf('http://127.0.0.1') === -1) {
    if (token) {
      config.headers['Authorization'] = 'bearer ' + token // 让每个请求携带自定义 token 请根据实际情况自行修改
    }
    config.headers['api-version'] = 'v1'
  } else {
    delete config.headers['api-version']
    delete config.headers['Authorization']
  }
  return config
}, err)

// response 返回接受配置
service.interceptors.response.use((response) => {
  if (response.config.responseType === 'blob') {
    return response
  }
  return response.data
}, err)

// 定义错误异常
const err = (error) => {
  if (error.response) {
    const data = error.response.data
    const token = localStorage.getItem(ACCESS_TOKEN)
    if (error.response.status === 403) {
      notification.error({
        message: 'Forbidden',
        description: data.message
      })
    }
    if (error.response.status === 401 && !(data.result && data.result.isLogin)) {
      if (token) {
        store.dispatch('Logout').then(() => {
          setTimeout(() => {
            window.location.reload()
          }, 1500)
        })
      }
    }
  }
  return Promise.reject(error)
}


const blobAjax = (rUrl, method, callback, data) => {
  const x = new XMLHttpRequest()
  // x.open(method, process.env.VUE_APP_REQUEST_URL + rUrl, true)
  x.open(method, rUrl, true)
  x.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
  x.responseType = 'blob'
  if (localStorage.getItem(ACCESS_TOKEN)) {
    x.setRequestHeader('Authorization', 'bearer ' + localStorage.getItem(ACCESS_TOKEN))
  }
  x.onload = function (e) {
    const headers = x.getAllResponseHeaders()
    // Convert the header string into an array
    // of individual headers
    const arr = headers.trim().split(/[\r\n]+/)
    // Create a map of header names to values
    const headerMap = {}
    arr.forEach(function (line) {
      const parts = line.split(': ')
      const header = parts.shift()
      const value = parts.join(': ')
      headerMap[header] = value
    })

    callback(e, headerMap)
  }
  if (data) {
    x.send(JSON.stringify(data))
  } else {
    x.send()
  }
}

最后把拦截器暴露出来,后面可以直接在接口中进行使用

export {
  service as axios,
  blobAjax
}

我这里把下载的机制也写了下,也是之前项目中带的,顺手拿过来分享给大家

第五步,刚才定义拦截器大家看到了引入了vuex,其实vuex应该是先去做好的,我给忘记了,所以写在这里吧,安装步骤就不赘述了,直接说下使用:

首先,安装完之后定义一个store目录,这个目录用于存放瓶瓶罐罐,先给大家看下我的目录吧

Vue+antd前端篇——项目构建+路由守卫+请求拦截+VUEX_第2张图片

在这里我把仓库细分开来了,user作为用户状态单独管理,后期如果有其他模块需要进行管理的状态在进行单独定义即可。

其次,定义好store目录后创建一个index文件,我们都知道vuex核心的点就是stategettersactionsmutationsmodules组成:

import Vue from 'vue'
import Vuex from 'vuex'

import user from './modules/user'
import getters from './getters'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    user
  },
  mutations: {

  },
  actions: {

  },
  getters
})

state:Vuex使用来存储应用中需要共享的状态。为了能让 Vue 组件在更改后也随着更改,需要基于state创建计算属性。

getters:类似于 Vue 中的 计算属性(可以认为是 store 的计算属性),getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

actions:actions并不能直接更改state的状态,它通过调用mutations来进行更改,通常在使用的时候是通过参数解构的方式调用commit来进行修改操作,actions处理异步方式可以参考官网或项目代码。

mutations:mutations可以说是actions的执行者,获取actions需要修改的内容。

modules:基于项目实际情况考虑,如果项目较大,且管理状态的内容较多,建议将store分割,使每个模块都独立拥有getters、actions、mumations、actions,便于管理。

import { ACCESS_TOKEN, USER_INFO } from '@/store/mutation-type'
import api from '../../api/login'

const user = {
  state: {
    info: {},
    token: '',
  },
  mutations: {
    SET_TOKEN (state, token) {
      state.token = token
    },
    SET_USER_INFO (state, info) {
      state.info = info
    }
  },
  actions: {
    Login ({commit}, userInfo) {
      return new Promise ((resolve,reject) => {
        api.login(userInfo).then(response => {
          if (response.code == 0) {
            localStorage.setItem(ACCESS_TOKEN, response.data.accessToken)
            localStorage.setItem(USER_INFO, response.data.user)
            commit('SET_TOKEN', response.data.accessToken)
            commit('SET_USER_INFO', response.data.user)
            resolve()
          } else {
            reject(response.data.message)
          }
        }).catch(error => {
          reject(error)
        })
      })
    },
    Logout ({commit},state) {
      return new Promise(resolve => {
        commit('SET_TOKEN','')
        commit('SET_USER_INFO',{})
        localStorage.removeItem(ACCESS_TOKEN)
        localStorage.removeItem(USER_INFO)
        resolve()
      })
    }
  }
}
export default user

以上便是vuex的核心知识点,说实话,我只会用,了解基本原理概念,太深入的东西我也没有去研究,仓库这里确实不是很好理解,以前没有做大型项目的时候基本用不到,所以长期以来vuex可以说是vue全家桶的短板吧,自此我也总结了下学习方法,那就是不会的东西,先找个参考去写,多写几遍,然后再去官网看资料,然后再去研究自己写的,自然而然就会了,当然了,这个是笨办法。

总结

自此一个项目的简单架构便搭建完成了,整个项目的重点:1.请求拦截器;2.路由守卫;3.vuex仓库管理,希望各位同学在实践的时候一边看官网,一边找参考去理解。

其实在实际项目开发中,这些工作一般都有架构师去做,即使没有架构师,网上也有很多的成熟架构供使用。当然了,用别人的和自己会造还是两码事

下一篇将讲述如何配置架构的相关文件,敬请期待...

git地址:https://gitee.com/jacky_201314/vue_antd_infrastructure

你可能感兴趣的:(vuex,antdesign,vue,vue.js,es6)