cli3 从搭建到优化的详细步骤(3)

如果创建项目的时候,选择了 vuex ,那么默认会在 src 目录下有一个 store.js 作为仓库文件。但在更多实际场景中,如果引入 vuex ,那么肯定避免不了分模块,先来看一下默认文件代码:

import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { } })

那么现在改造一下,比如先划分出 app 、 user 两个模块,可以这样:

import Vue from 'vue' import Vuex from 'vuex' import app from './store/modules/app' import user from './store/modules/user' import getters from './store/getters' Vue.use(Vuex) const store = new Vuex.Store({ modules: { app, user }, getters }) export default store

在 src/ 下创建 store/ 目录:

cli3 从搭建到优化的详细步骤

app module 可以用来存储应用的状态,比如接下来要讲到的全局 loading ,或者控制第三方组件的全局大小,比如 element ui 中的全局组件 size ;

user module 可以用来存储当前用户的信息;

当然,store 配合本地存储比较完美,这里采用 js-cookie 。

全局loading、合理利用vue router守卫

全局loading

上面说完了 axios、vuex ,现在结合之前说一下设置全局 loading 效果。

平常写代码每个请求之前一般都需要设置 loading ,成功之后结束 loading 效果,这就迫使我们不得不写大量重复代码,如果不想这样做,可以结合 axios 和 vuex 统一做了。

首先,在说 vuex 的时候,我在 src/ 下创建了一个 store ,现在就在 store/modules/app.js 写这个 Loading 效果的代码;

const app = { state: { requestLoading: 0 }, mutations: { SET_LOADING: (state, status) => { // error 的时候直接重置 if (status === 0) { state.requestLoading = 0 return } state.requestLoading = status ? ++state.requestLoading : --state.requestLoading } }, actions: { SetLoading ({ commit }, status) { commit('SET_LOADING', status) } } } export default app

再来修改一下 utils/request.js

import axios from 'axios' import store from '@/store' // 创建axios 实例 const service = axios.create({ baseURL: process.env.BASE_API, // api的base_url timeout: 10000 // 请求超时时间 }) // request 拦截器 service.interceptors.request.use( config => { // 这里可以自定义一些config 配置 // loading + 1 store.dispatch('SetLoading', true) return config }, error => { // 这里处理一些请求出错的情况 // loading 清 0 setTimeout(function () { store.dispatch('SetLoading', 0) }, 300) console.log(error) Promise.reject(error) } ) // response 拦截器 service.interceptors.response.use( response => { const res = response.data // 这里处理一些response 正常放回时的逻辑 // loading - 1 store.dispatch('SetLoading', false) return res }, error => { // 这里处理一些response 出错时的逻辑 // loading - 1 store.dispatch('SetLoading', false) return Promise.reject(error) } ) export default service

其次,在 src/components/ 下创建 RequestLoading.vue 组件:

<template> <transition mode="out-in"> <div v-if="requestLoading"> <svg-icon icon-class="loading" /> </div> </transition> </template> <script> import { mapGetters } from 'vuex' export default { name: 'RequestLoading', computed: { ...mapGetters([ 'requestLoading' ]) } } </script> <style lang='scss' scoped> .request-loading-component { position: fixed; left: 0; right: 0; top: 0; bottom: 0; //background-color: rgba(48, 65, 86, 0.2); background-color: transparent; font-size: 150px; display: flex; flex-direction: row; justify-content: center; align-items: center; z-index: 999999; } </style>

最后,在 app.vue 中引入即可。

附: 为了方便演示,项目里出了初始化包括 axios 、 vuex 、 vue-router , 项目使用了 js-cookie 、 element-ui 等,此步骤之后,会改造一下 app.vue ;

vue router守卫

vue-router 提供了非常方便的钩子,可以让我们在做路由跳转的时候做一些操作,比如常见的权限验证。

首先,需要在 src/utils/ 下创建 auth.js ,用于存储token;

import Cookies from 'js-cookie' const TokenKey = 'project-token' export function getToken () { return Cookies.get(TokenKey) } export function setToken (token) { return Cookies.set(TokenKey, token) } export function removeToken () { return Cookies.remove(TokenKey) }

在 src/utils/ 下创建 permission.js :

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e460d8181717024e57ff75043c596867.html