vue管理系统项目中的一些核心技能汇总

目录
  • 前言
  • 1. Axios 拦截器和二次封装
    • 1.1 Axios 请求和响应拦截器。
    • 1.2 Axios 二次封装
  • 2. Vuex 的数据持久化
  • 3. 路由守卫和动态路由的挂载
    • 3.1 路由守卫
    • 3.2 动态路由的挂载
  • 4. 环境变量的配置文件
  • 5. 封装一个按钮级权限的自定义指令
  • 总结

前言

很多脚手架搭建的 vue 的管理系统项目,其核心模块的处理方式大致上都是一样的。

所以,我结合之前项目,整理了一下重要模块的解决方案。

1. Axios 拦截器和二次封装

1.1 Axios 请求和响应拦截器。

// 引入 vue 和 axios 模块
import Vue from 'vue'
import axios from 'axios'
// 环境变量中的请求地址
const baseURL = process.env.VUE_APP_API_BASE_URL

// axios 的配置变量
const config = {
  baseURL: baseURL,
  timeout: 1000 * 60 * 3 // Timeout
}

// 创建 axios 实例
const _axios = axios.create(config)

// axios 的请求拦击器
_axios.interceptors.request.use(
  function (config) {
    // 每发起一次请求时,将本地存储的 token 值添加到请求头中。
    const token = Vue.ls.get(ACCESS_TOKEN)
    config.headers['token'] = token
    // 返回新的配置项
    return config
  },
  // 失败 则返回失败信息
  function (error) {
    return Promise.reject(error)
  }
)

// axios 的响应拦击器
_axios.interceptors.response.use(
  function (response) {
    // 解构出响应对象中的 code 和 msg
    const { code, msg } = response.data
    // 响应头中的 content-type 类型
    const _content_type = response.headers['content-type']
    // 是否为导出
    if (_content_type === _export) {
      return Promise.resolve(response)
    }
    // 匹配 code 值,和后端约定。
    // 0:响应成功-返回响应体;20000:用户token为空 20001:用户信息为空。20002:登录失效,请重新登录。
    switch (code) {
      case 0:
        return Promise.resolve(response)
      case 20000:
      case 20001:
      case 20002:
        router.replace({ path: '/login' })
        return Promise.reject(msg)
      default:
        return msg && Promise.reject(msg)
    }
  },
  // 失败 则返回失败信息
  function (error) {
    return Promise.reject(error.message)
  }
)

1.2 Axios 二次封装

import notification from 'ant-design-vue/es/notification'
/**
 * GET 方法
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @returns Promise
 */
export function httpGet (url, params) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: params
    })
      .then(res => {
        resolve(res.data)
      })
      .catch(err => {
        console.warn(err, 'WARN')
        reject(err)
      })
  })
}

/**
 *
 * POST 方法
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @returns Promise
 */
export function httpPost (url, params) {
  return new Promise((resolve, reject) => {
    axios.post(url, params)
      .then(res => {
        resolve(res.data)
      })
      .catch(err => {
        if (err === undefined || err.__CANCEL__) {
          return false
        }
        notification.error({
          title: '错误',
          message: err
        })
        reject(err)
      })
  })
}

2. Vuex 的数据持久化

Vuex 中的数据在经过页面刷新后,值都会被重制为初始化状态。Vuex 的数据持久化,可以保证页面刷新后数据的不变性。

很简单的处理方式。

分析:页面在刷新后,Vue 引用重新加载 main.js 入口文件,这时也就加载了写入的 js 文件(用来处理重新往 Vuex 中的塞值操作)。

// mian.js
import bootstrap from './core/bootstrap'

// ./core/bootstrap.js
import Vue from 'vue'
import store from '@/store/'

export default function Initializer () {
  store.commit('SET_TOKEN', Vue.ls.get('ACCESS_TOKEN'))
  store.commit('SET_MENUS', Vue.ls.get('MENU_LIST'))
  store.commit('SET_USER_BTN', Vue.ls.get('USER_BTN'))
}

3. 路由守卫和动态路由的挂载

3.1 路由守卫

路由守卫,正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。

你可以使用 router.beforeEach 注册一个全局前置守卫和 router.afterEach 全局后置钩子:

import router from '@/router'

import NProgress from 'nprogress' // 进度条
import 'nprogress/nprogress.css' // 进度条样式

// 全局前置守卫
router.beforeEach((to, from, next) => {
    // 进度条开始
  NProgress.start()
  // 判读本地存储中是否由 Token
  if (Vue.ls.get(ACCESS_TOKEN)) {
    if (to.path === '/login') { // 跳转到 login 放行,然后结束进度条。
      next()
      NProgress.done()
    } else { // 跳转其他
      // 动态路由的挂载,见 3.2 动态路由的挂载
      ...
    }
  } else {
    if (whiteList.includes(to.name)) {
      next()
    } else {
      next('/login')
      NProgress.done()
    }
  }
})

// 全局后置钩子
router.afterEach(() => {
  NProgress.done()
})

3.2 动态路由的挂载

动态路由的挂载的逻辑也是在“全局前置守卫”中进行的处理。

if (Vue.ls.get(ACCESS_TOKEN)) {
  if (to.path === '/login') {
    next()
    NProgress.done()
  } else { // 跳转其他
    // 判读 vuex store 中 has 的变量标识
    const has = store.getters.has
    // 没有 has 变量,动态的添加路由
    if (!has) {
      // 获取本地存储中的后端路由数据
      const menus = Vue.ls.get(MENU_LIST)
      // 调用 Vuex 中的 GenerateRoutes 异步方法将路由数据进行追加处理
      store
        .dispatch('GenerateRoutes', menus)
        .then(res => {
          // 追加挂载处理
          router.addRoutes(store.getters.addRouters)
          // decodeURIComponent 将已编码 URI 中所有能识别的转义序列转换成原字符。
          const redirect = decodeURIComponent(to.path)
          if (to.path === redirect) {
            // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
            next({ ...to, replace: true })
          } else {
            // 跳转到目的路由
            next({ path: redirect })
          }
        })
        .catch(() => {
          // 错误处理
          notification.error({
            message: '错误',
            description: '请求用户信息失败,请重新登录'
          })
          next('/login')
        })
    } else { // 有 has 变量,放行,跳转。
      next()
    }
  }
}

4. 环境变量的配置文件

生产环境和开发环境用的服务器地址、端口号都不一样,这时我们需要配置环境变量的文件,以在不同环境使用对应的请求地址。

文件一般分为 .env 和 .env.development 文件。

  • .env:是生产环境读取的环境变量文件。
  • .env.development:是开发环境读取的环境变量文件。

也可以根据不同环境定制文件。如:.env.test217 文件。

相应的需要在 package.json 文件中配置对应的命令,在 CI 过程中注意修改下指令的名称即可。

// package.json
"scripts": {
  "serve": "vue-cli-service serve",
  "build": "vue-cli-service build",
  "test217": "vue-cli-service build --mode test217",
},
  • npm run serve 命令读取的是 .env.development 文件中的环境变量
  • npm run build 命令读取的是 .env 文件中的环境变量
  • npm run test217 命令读取的是 .env.test217 文件中的环境变量
// .env
NODE_ENV = 'production'
VUE_APP_FLAG = 'pro'
VUE_APP_API_BASE_URL='https://xx.ss.com/api'
// .env.development
NODE_ENV = 'development'
VUE_APP_FLAG = 'dev'
VUE_APP_API_BASE_URL='http://127.0.0.1:80/api'
// .env.test217
NODE_ENV = 'production'
VUE_APP_FLAG = 'dev'
VUE_APP_API_BASE_URL='http://127.0.0.1:8087/api'

axios 中的 config 中的 baseURL 变量就可以这样根据不同的环境设置了。process.env 是全局变量,可以直接访问 .env 文件中的变量。

const baseURL = process.env.VUE_APP_API_BASE_URL

5. 封装一个按钮级权限的自定义指令

  • 在入口文件 main.js 中引入自定义指令的文件。
// main.js
import './directives/action'
  • Code feature
// 引入 Vue 和 store
import Vue from 'vue'
import store from '@/store'

/*
* 定义一个函数表达式
* action - 指令名称
* inserted - 被绑定的元素插入父节点的时候调用(父节点存在即可调用,不必存在document中)
*/
const action = Vue.directive('action', {
  inserted: function (el, binding, vnode) {
    const actionName = binding.arg
    // Vuex Store 中的 userBtn 数据
    const userBtn = store.getters.userBtn
    // 当前路由中的 menuId
    const menuId = vnode.context.$route.meta.menuId
    // 过滤出按钮的 list
    const btnList = userBtn.filter(item => item.pId === menuId && item.mType === 2)
    // 判读值是否在 btnList 中,在返回 false,否则返回 true。
    function _has (value) {
      let isExist = true
      for (let i = 0; i < btnList.length; i++) {
        if (btnList[i].identifier && btnList[i].identifier === value) {
          isExist = false
        }
      }
      return isExist
    }
    // 判断按钮是否在btnList中,不在就删除或移除改按钮 DOM。
    if (_has(actionName)) {
      el.parentNode && el.parentNode.removeChild(el) || (el.style.display = 'none')
    }
  }
})

// 导出默认这个函数表达式
export default action

总结

到此这篇关于vue管理系统项目中的一些核心技能汇总的文章就介绍到这了,更多相关vue项目核心技能内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue axios登录请求拦截器

    当我们在做接口请求时,比如判断登录超时时候,通常是接口返回一个特定的错误码,那如果我们每个接口都去判断一个耗时耗力,这个时候我们可以用拦截器去进行统一的http请求拦截. 1.安装配置axios cnpm install --save axios  我们可以建一个js文件来做这个统一的处理,新建一个axios.js,如下 import axios from 'axios' import { Indicator } from 'mint-ui'; import { Toast } from 'mi

  • vuex数据持久化的两种实现方案

    目录 业务需求: 方案一:vuex-persistedstate 方案二:vuex-persist 总结 业务需求: 在基于vue开发SPA项目时,为了解决页面刷新后数据丢失的问题,我们一般都是将数据存储在localstorage或sessionstorage中:当数据需要全局处理统一管理时,我们也会借助于vue官方提供的vuex来进行数据的统一管理.vuex相比localstorage或sessionstorage来说,存储数据更安全些.与此同时,vuex也存在一些弊端,当页面刷新后,vuex

  • 详解Vue中使用Axios拦截器

    需求是拦截前端的网络请求和相应. 废话不多说,直接上干货. 我用的是vue-cli3所以这个config文件是我自己创建的. 先介绍env.js //根据不同的环境更改不同的baseUrl let baseUrl = ''; //开发环境下 if (process.env.NODE_ENV == 'development') { baseUrl = ''; } else if (process.env.NODE_ENV == 'production') { baseUrl = '生产地址'; }

  • VUEX 数据持久化,刷新后重新获取的例子

    VUEX 数据持久化 // store.js getters: { userInfo(state) { console.log('getters',state); if (!state.userInfo.id) { let token = getStorage("token"); console.log('token',token); if (token) { let userInfo = getStorage("userInfo"); state.userInfo

  • Vue中axios拦截器如何单独配置token

    在了解到cookie.session.token的作用后学习token的使用 cookie cookie是随着url将参数发送到后台,安全性最低,并且大小受限,不超过4kb左右,它的数据保存在客户端 session session数据保存在服务端,在内存中开辟空间存储数据,session文件名即sessionID保存在cookie内,随cookie传送到服务端后在服务端匹配session文件 token token是服务端的一种算法,如果登录成功,服务端就会根据算法生成一个字符串,将字符串传递回

  • vue 路由守卫(导航守卫)及其具体使用

    最近在学习vue,感觉路由守卫这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记 官方文档 导航守卫其实也是路由守卫,也可以是路由拦截,我们可以通过路由拦截,来判断用户是否登录,该页面用户是否有权限浏览,需要结合meta来实现 vue中路由守卫一共有三种,一个全局路由守卫,一个是组件内路由守卫,一个是router独享守卫 所谓的路由守卫可以简单的理解为一座房子的门口的保安,想要进入这个房子就必须通过保安的检查,要告诉路由守卫你从哪里来?总不能随便陌生人就给放进去?要到哪里去?然后保安再告

  • vue管理系统项目中的一些核心技能汇总

    目录 前言 1. Axios 拦截器和二次封装 1.1 Axios 请求和响应拦截器. 1.2 Axios 二次封装 2. Vuex 的数据持久化 3. 路由守卫和动态路由的挂载 3.1 路由守卫 3.2 动态路由的挂载 4. 环境变量的配置文件 5. 封装一个按钮级权限的自定义指令 总结 前言 很多脚手架搭建的 vue 的管理系统项目,其核心模块的处理方式大致上都是一样的. 所以,我结合之前项目,整理了一下重要模块的解决方案. 1. Axios 拦截器和二次封装 1.1 Axios 请求和响应

  • vue.js项目中实用的小技巧汇总

    前言 Vue.js 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合.另一方面,Vue 完全有能力驱动采用单文件组件和 Vue 生态系统支持的库开发的复杂单页应用. # 在Vue 项目中引入Bootstrap 有时在vue项目中会根据需求引入Bootstrap,而Bootstrap又是依赖于jQuery的,在使用npm安装时,可能会出现一系列的错误 1.安装jQuery

  • 详解vue在项目中使用百度地图

    第一步,去百度地图开发者申请秘钥. 第二步在项目中引入,具体如下 其中index.html存放地图链接,代码如下 然后在APP.vue里面实现,代码如下 <template> <div id="app"> <div id="allmap" ref="allmap"></div> <router-view></router-view> </div> </tem

  • vue+element项目中过滤输入框特殊字符小结

    可以在main.js中写入方法 Vue.prototype.validSe = function (value, number = 255) { value = value.replace(/[`-*~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]·~!@#¥%--&*()--\-+={}|<>?:""[].:'',..]/g, '').replace(/\s/g, ""); if (value.

  • 解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题

    vue +webpack 项目中数据更新后页面没有刷新问题,ie11下,如果GET请求请求相同的URL,默认会使用之前请求来的缓存数据,而不会去请求接口获取最新数据,我用的解决方法是在每个请求发送前,拦截请求并给请求接口的URL后加一个时间戳(new Date().getTime()),这样就保证了每一次请求的URL都不同,ie11就会不断的请求接口而不使用缓存数据. 代码如下 if(config.url.indexOf('?')>-1){ config.url = url + config.u

  • Vue.js项目中管理每个页面的头部标签的两种方法

    在 Vue SPA 应用中,如果想要修改 HTML 的头部标签,如页面的 title ,我们只能去修改 index.html 模板文件,但是这个是全局的修改,如何为每个页面都设置不一样的 title 呢?下面介绍两种方法. 使用router.meta 在路由里面配置每个路由的地址: routes: [ { /* (首页)默认路由地址 */ path: '/', name: 'Entrance', component: Entrance, meta: { title: '首页入口' } }, {

  • Vue项目中常用的实用技巧汇总

    目录 前言 1. 使用 $attrs 和 $listeners 进行多层级的数据和事件传递 2. 实现数据的双向绑定,方便维护数据 使用 .sync 实现 Prop 的"双向绑定" 使用 model 选项 3. 使用 Mixins 4. 使用动态组件去懒加载组件 5. 在组件作用域内的 CSS 中使用 ::v-deep  修改组件样式 6. 使用装饰器优化代码 7. 利用 require.context 去获取项目目录信息 总结 引用 前言 在 Vue 项目开发中,很容易产生一些问题,

  • Vue开发项目中如何使用Font Awesome 5

    目录 安装依赖 配置 使用 1. 进入图标搜索页 2. 输入想使用的图标的英文,例如用户的英文是 user 3. 过滤收费图标 4.点击图标查看 5. 查看结果 总结 Font Awesome 官网:https://fontawesome.com/ 前端小伙伴们都知道Font Awesome图标库,它具有丰富的常用图标,笔者开发时也经常使用,省却了自己到处找图标的困扰,当然阿里的iconfont也不错,不过它比较杂乱,找的图标有时候不是配套的,尺寸和比例上有些偏差,即使你只使用某一个图标库的图标

  • vue整合项目中百度API示例详解

    目录 官网介绍 申请密钥 官方示例 项目实战 创建地图 获取经纬度 创建Map实例 两个坐标点之间的距离 查询地点信息 Vue项目中整合百度API获取地理位置的方法 组件中使用 vue-baidu-map 百度地图官方vue组件 官网介绍 百度地图 JavaScript API 是一套由 JavaScript 语言编写的应用程序接口 可帮助您在网站中,构建功能丰富交互性强的地图应用 支持PC端和移动端,基于浏览器的地图应用开发,且支持HTML5特性的地图开发 官网传送门 百度地图JavaScri

  • ejsExcel模板在Vue.js项目中的实际运用

    什么是ejsExcel? ejsExcel是一款国人开发的.在Node.js应用程序中使用我们预先设置好的Excel模板导出Excel表格的模板引擎. Excel模板 导出后 Github地址 ejsExcel 如果因为众(ni)所(dong)周(de)知的原因打不开github,没有关系,它的语法很简单,都是一些对Excel模板格式的定义: 这篇文章是我在工作中因为业务需要,用到了ejsExcel这个模板引擎,觉得很不错,但是坑也不少.而网上相关的资料又太少,所以趁此机会总结了一下我的踩坑经历

随机推荐