vue的接口封装和状态管理

Posted 草长莺飞飞满天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue的接口封装和状态管理相关的知识,希望对你有一定的参考价值。

 

1.config index.js下面的跨域代理设置:

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

proxyTable: 
/api:
target: http://xxxx, //要访问的后端接口
changeOrigin: true,
pathRewrite:
^/api: http://xxx

,
,

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

2.http.js(封装axios

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import Vue from vue
import axios from axios
import QS from qs //视情况用于不用;
import Loading, Message from element-ui;
import store from ../store/index

let loading //定义loading变量

function startLoading() //使用Element loading-start 方法
loading = Loading.service(
lock: true,
text: 努力加载中……,
background: rgba(0, 0, 0, 0.5)
)


function endLoading() //使用Element loading-close 方法
loading.close()


//那么 showFullScreenLoading() tryHideFullScreenLoading() 要干的事儿就是将同一时刻的请求合并。
//声明一个变量 needLoadingRequestCount,每次调用showFullScreenLoading方法 needLoadingRequestCount + 1。
//调用tryHideFullScreenLoading()方法,needLoadingRequestCount - 1。needLoadingRequestCount为 0 时,结束 loading。
let needLoadingRequestCount = 0
export function showFullScreenLoading()
if (needLoadingRequestCount === 0)
startLoading()

needLoadingRequestCount++


export function tryHideFullScreenLoading()
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0)
endLoading()



let baseWebURL = ;
// 环境的切换
if (process.env.NODE_ENV == development) //开发环境
baseWebURL = /api + /api;(多加一个api是后台那边统一拦截处理视项目情况而定加不加)
else if (process.env.NODE_ENV == test) //测试环境
baseWebURL = https://www.test.com;
else if (process.env.NODE_ENV == production) //生产环境
baseWebURL = http://www.producetion.com;

//生成一个axios实例
var instance = axios.create(
baseURL: baseWebURL,
);
console.log(instance, instance)
//1.请求超时时间
instance.defaults.timeout = 10000;
//2.post请求头
instance.defaults.headers.post[Content-Type] = application/x-www-form-urlencoded;charset=UTF-8;
//3.公共部分(请求带token设置)
//instance.defaults.headers.common[Authorization] = store.state.token;
//4.返回数据类型的定义
//instance.defaults.responseType = json;
//5.带cookie请求
instance.defaults.withCredentials = true

// 请求拦截器
instance.interceptors.request.use(
config =>
console.log(config, config请求拦截器)
//1.全局loadin配置
/*2.token校验:一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地;
然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token;
如果token存在说明用户已经登陆过则更新vuex中的token状态;
然后,在每次请求接口的时候,都会在请求的header中携带token;
后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。
v1.每次发送请求之前判断vuex中是否存在token
v2.如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
v3.即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断*/
const token = store.state.token;
alert(token,token)
token && (config.headers.Authorization = token);
if (config.method == post)
console.log(post请求统一需要做什么判断)

//config.headers.Accept = application/json; //规定接受形式json格式
showFullScreenLoading() //开启loading
return config;
, error =>
return Promise.reject(error);
);

// 响应拦截器
instance.interceptors.response.use(
response =>
console.log(response, response响应拦截器)
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
//否则的话抛出错误
if (response.status === 200)
tryHideFullScreenLoading() //关闭loading
Message(
showClose: true,
message: 响应成功,
type: success
)
return Promise.resolve(response);
else
return Promise.reject(response);

, error =>
console.log(error, error)
if (error.response.data.status)
console.log(后台错误码统一处理)
switch (error.response.data.status)
// 401:未登录;未登录则跳转登录页面,并携带当前页面的路径;在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace(
path: /login,
query:
redirect: router.currentRoute.fullPath

);
break;
// 403:token过期;登录过期对用户进行提示;清除本地token和清空vuex中token对象;跳转登录页面
case 403:
Message(
showClose: true,
message: 登录过期,请重新登录,
duration: 1000,
type: warning
)
//清除token
localStorage.removeItem(userToken);
store.commit(LOGIN_OUT, null);
//跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() =>
router.replace(
path: /login,
query:
redirect: router.currentRoute.fullPath

);
, 1000);
break;
//404请求不存在
case 404:
Message(
showClose: true,
message: 网络请求不存在,
duration: 1000,
type: error
)
break;
//其他错误,直接抛出错误提示
default:
Message(
showClose: true,
message: error.response.data.message,
duration: 1000,
type: error
)


return Promise.reject(error);
);


// 封装axios的get请求
export function getData(url, params)
return new Promise((resolve, reject) =>
instance.get(url, params).then(response =>
resolve(response.data);
)
.catch(error =>
reject(error);
);
);

// 封装axios的post请求
export function postData(url, params)
return new Promise((resolve, reject) =>
instance.post(url, QS.stringify(params)).then(response =>
resolve(response.data);
)
.catch(error =>
reject(error);
);
);

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

3.api.js(封装接口)

import  postData, getData  from ./http.js

export function cityList(data = )
return postData(/xxxx/xx, data);

4.vuex构成

(1)index.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import Vue from vue;
import Vuex from vuex;
import state from ./state
import mutations from ./mutations
import getters from ./getters
import actions from ./actions
Vue.use(Vuex);

const store = new Vuex.Store(
state,
mutations,
getters,
actions
);

export default store;

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(2)state.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

export default 
state:
// 存储token
token: localStorage.getItem(userToken) ? localStorage.getItem(userToken) :

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(3)mutation-types.js (常量)

export const LOGIN_IN = LOGIN_IN;//登入
export const LOGIN_OUT = LOGIN_OUT;//登出

(4)mutation.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import * as type from ./mutation-types
export default
//登入
[type.LOGIN_IN](state, token)
state.token = token;
localStorage.setItem(userToken, token);
,
//登出 or 退出登入
[type.LOGIN_OUT](state, token)
localStorage.removeItem("userToken", token);
state.token = token;
,

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(5)actions (这里是异步操作)

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

export default
//actions这里提交的是mutation
getLoginInInfo(commit,token)
commit(LOGIN_IN,token)
,
getLoginOutInfo(commit,token)
commit(LOGIN_OUT,token)

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(6)getters.js  视情况放什么获取state更改后的值

(7)路由 router下面的index.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import Vue from vue
import Router from vue-router
import store from ../store/index
//方式一:最简单直接的使用组件
//import HelloWorld from @/components/HelloWorld
//import Test from @/components/test

//方式二:webpack自带的模块按需加载 r就是resolve
//const HelloWorld = r => require.ensure([], () => r(require(@/components/HelloWorld)), HelloWorld);

Vue.use(Router)

const router = new Router(
mode: history, //去掉地址栏#号
routes: [
path: /,
name: testMain,
meta:
title: 系统首页,
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
,
component: resolve => require([@/components/testMain], resolve) //测试首页
,
path: /login,
name: login,
meta:
title: 登入,
,
component: resolve => require([@/components/login], resolve) //模拟登入------(方式三:懒加载方式)
,
path: /HelloWorld,
name: HelloWorld,
meta:
requireAuth: true,
title: 测试二级联动路由传参,
,
component: resolve => require([@/components/HelloWorld], resolve) //测试二级联动路由传参
,
path: /test,
name: test,
meta:
requireAuth: true,
title: 测试参数解码,
,
component: resolve => require([@/components/test], resolve) //测试参数解码
,
path: /testEgdit,
name: testEgdit,
meta:
requireAuth: true,
title: 富文本编辑器试用,
,
component: resolve => require([@/components/testEgdit], resolve) //富文本编辑器试用
,
path: /testElementComponent,
name: testElementComponent,
meta:
requireAuth: true,
title: element ui组件测试,
,
component: resolve => require([@/components/testElementComponent], resolve) //element ui 组件测试
,
path: /tableTest,
name: tableTest,
meta:
requireAuth: true,
title: element ui表格组件测试,
,
component: resolve => require([@/components/tableTest], resolve) //element ui table组件测试
,
path: /echartTest,
name: echartTest,
meta:
requireAuth: true,
title: echart插件测试,
,
component: resolve => require([@/components/echartTest], resolve) //echart插件测试
,
path: *,
name: notFound,
meta:
title: 404页面,
,
component: resolve => require([@/components/notFound], resolve) //全不匹配的情况下,返回404,路由按顺序从上到下,依次匹配。最后一个*能匹配全部
]
)

router.beforeEach((to, from, next) =>
//可以做 loadong 开始加载 效果
store.state.token = localStorage.getItem(userToken); //获取本地存储的token
if (to.meta.title) //判断是否有标题 该操作可以再监听路由时候处理 watch:$route(to,from)xxx操作
document.title = to.meta.title

if (to.meta.requireAuth) // 判断该路由是否需要登录权限
if (store.state.token) // 通过vuex state获取当前的token是否存
console.log(有token时候, to, from, next)
next();
else
console.log(没有token时候, to)
next(
path: /login,
query: redirect: to.fullPath // 将跳转的路由path作为参数,登录成功后跳转到该路由
)

else
next();

)

router.afterEach(route =>
//loading加载完成
);

export default router;

vue的接口封装和状态管理_ios

          « ​上一篇: pdf.js使用详解


1.config index.js下面的跨域代理设置:

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

proxyTable: 
/api:
target: http://xxxx, //要访问的后端接口
changeOrigin: true,
pathRewrite:
^/api: http://xxx

,
,

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

2.http.js(封装axios)

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import Vue from vue
import axios from axios
import QS from qs //视情况用于不用;
import Loading, Message from element-ui;
import store from ../store/index

let loading //定义loading变量

function startLoading() //使用Element loading-start 方法
loading = Loading.service(
lock: true,
text: 努力加载中……,
background: rgba(0, 0, 0, 0.5)
)


function endLoading() //使用Element loading-close 方法
loading.close()


//那么 showFullScreenLoading() tryHideFullScreenLoading() 要干的事儿就是将同一时刻的请求合并。
//声明一个变量 needLoadingRequestCount,每次调用showFullScreenLoading方法 needLoadingRequestCount + 1。
//调用tryHideFullScreenLoading()方法,needLoadingRequestCount - 1。needLoadingRequestCount为 0 时,结束 loading。
let needLoadingRequestCount = 0
export function showFullScreenLoading()
if (needLoadingRequestCount === 0)
startLoading()

needLoadingRequestCount++


export function tryHideFullScreenLoading()
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0)
endLoading()



let baseWebURL = ;
// 环境的切换
if (process.env.NODE_ENV == development) //开发环境
baseWebURL = /api + /api;(多加一个api是后台那边统一拦截处理视项目情况而定加不加)
else if (process.env.NODE_ENV == test) //测试环境
baseWebURL = https://www.test.com;
else if (process.env.NODE_ENV == production) //生产环境
baseWebURL = http://www.producetion.com;

//生成一个axios实例
var instance = axios.create(
baseURL: baseWebURL,
);
console.log(instance, instance)
//1.请求超时时间
instance.defaults.timeout = 10000;
//2.post请求头
instance.defaults.headers.post[Content-Type] = application/x-www-form-urlencoded;charset=UTF-8;
//3.公共部分(请求带token设置)
//instance.defaults.headers.common[Authorization] = store.state.token;
//4.返回数据类型的定义
//instance.defaults.responseType = json;
//5.带cookie请求
instance.defaults.withCredentials = true

// 请求拦截器
instance.interceptors.request.use(
config =>
console.log(config, config请求拦截器)
//1.全局loadin配置
/*2.token校验:一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地;
然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token;
如果token存在说明用户已经登陆过则更新vuex中的token状态;
然后,在每次请求接口的时候,都会在请求的header中携带token;
后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。
v1.每次发送请求之前判断vuex中是否存在token
v2.如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
v3.即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断*/
const token = store.state.token;
alert(token,token)
token && (config.headers.Authorization = token);
if (config.method == post)
console.log(post请求统一需要做什么判断)

//config.headers.Accept = application/json; //规定接受形式json格式
showFullScreenLoading() //开启loading
return config;
, error =>
return Promise.reject(error);
);

// 响应拦截器
instance.interceptors.response.use(
response =>
console.log(response, response响应拦截器)
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
//否则的话抛出错误
if (response.status === 200)
tryHideFullScreenLoading() //关闭loading
Message(
showClose: true,
message: 响应成功,
type: success
)
return Promise.resolve(response);
else
return Promise.reject(response);

, error =>
console.log(error, error)
if (error.response.data.status)
console.log(后台错误码统一处理)
switch (error.response.data.status)
// 401:未登录;未登录则跳转登录页面,并携带当前页面的路径;在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace(
path: /login,
query:
redirect: router.currentRoute.fullPath

);
break;
// 403:token过期;登录过期对用户进行提示;清除本地token和清空vuex中token对象;跳转登录页面
case 403:
Message(
showClose: true,
message: 登录过期,请重新登录,
duration: 1000,
type: warning
)
//清除token
localStorage.removeItem(userToken);
store.commit(LOGIN_OUT, null);
//跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() =>
router.replace(
path: /login,
query:
redirect: router.currentRoute.fullPath

);
, 1000);
break;
//404请求不存在
case 404:
Message(
showClose: true,
message: 网络请求不存在,
duration: 1000,
type: error
)
break;
//其他错误,直接抛出错误提示
default:
Message(
showClose: true,
message: error.response.data.message,
duration: 1000,
type: error
)


return Promise.reject(error);
);


// 封装axios的get请求
export function getData(url, params)
return new Promise((resolve, reject) =>
instance.get(url, params).then(response =>
resolve(response.data);
)
.catch(error =>
reject(error);
);
);

// 封装axios的post请求
export function postData(url, params)
return new Promise((resolve, reject) =>
instance.post(url, QS.stringify(params)).then(response =>
resolve(response.data);
)
.catch(error =>
reject(error);
);
);

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

3.api.js(封装接口)

import  postData, getData  from ./http.js

export function cityList(data = )
return postData(/xxxx/xx, data);

4.vuex构成

(1)index.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import Vue from vue;
import Vuex from vuex;
import state from ./state
import mutations from ./mutations
import getters from ./getters
import actions from ./actions
Vue.use(Vuex);

const store = new Vuex.Store(
state,
mutations,
getters,
actions
);

export default store;

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(2)state.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

export default 
state:
// 存储token
token: localStorage.getItem(userToken) ? localStorage.getItem(userToken) :

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(3)mutation-types.js (常量)

export const LOGIN_IN = LOGIN_IN;//登入
export const LOGIN_OUT = LOGIN_OUT;//登出

(4)mutation.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import * as type from ./mutation-types
export default
//登入
[type.LOGIN_IN](state, token)
state.token = token;
localStorage.setItem(userToken, token);
,
//登出 or 退出登入
[type.LOGIN_OUT](state, token)
localStorage.removeItem("userToken", token);
state.token = token;
,

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(5)actions (这里是异步操作)

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

export default
//actions这里提交的是mutation
getLoginInInfo(commit,token)
commit(LOGIN_IN,token)
,
getLoginOutInfo(commit,token)
commit(LOGIN_OUT,token)

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

(6)getters.js  视情况放什么获取state更改后的值

(7)路由 router下面的index.js

vue的接口封装和状态管理_iosvue的接口封装和状态管理_ios

import Vue from vue
import Router from vue-router
import store from ../store/index
//方式一:最简单直接的使用组件
//import HelloWorld from @/components/HelloWorld
//import Test from @/components/test

//方式二:webpack自带的模块按需加载 r就是resolve
//const HelloWorld = r => require.ensure([], () => r(require(@/components/HelloWorld)), HelloWorld);

Vue.use(Router)

const router = new Router(
mode: history, //去掉地址栏#号
routes: [
path: /,
name: testMain,
meta:
title: 系统首页,
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
,
component: resolve => require([@/components/testMain], resolve) //测试首页
,
path: /login,
name: login,
meta:
title: 登入,
,
component: resolve => require([@/components/login], resolve) //模拟登入------(方式三:懒加载方式)
,
path: /HelloWorld,
name: HelloWorld,
meta:
requireAuth: true,
title: 测试二级联动路由传参,
,
component: resolve => require([@/components/HelloWorld], resolve) //测试二级联动路由传参
,
path: /test,
name: test,
meta:
requireAuth: true,
title: 测试参数解码,
,
component: resolve => require([@/components/test], resolve) //测试参数解码
,
path: /testEgdit,
name: testEgdit,
meta:
requireAuth: true,
title: 富文本编辑器试用,
,
component: resolve => require([@/components/testEgdit], resolve) //富文本编辑器试用
,
path: /testElementComponent,
name: testElementComponent,
meta:
requireAuth: true,
title: element ui组件测试,
,
component: resolve => require([@/components/testElementComponent], resolve) //element ui 组件测试
,
path: /tableTest,
name: tableTest,
meta:
requireAuth: true,
title: element ui表格组件测试,
,
component: resolve => require([@/components/tableTest], resolve) //element ui table组件测试
,
path: /echartTest,
name: echartTest,
meta:
requireAuth: true,
title: echart插件测试,
,
component: resolve => require([@/components/echartTest], resolve) //echart插件测试
,
path: *,
name: notFound,
meta:
title: 404页面,
,
component: resolve => require([@/components/notFound], resolve) //全不匹配的情况下,返回404,路由按顺序从上到下,依次匹配。最后一个*能匹配全部
]
)

router.beforeEach((to, from, next) =>
//可以做 loadong 开始加载 效果
store.state.token = localStorage.getItem(userToken); //获取本地存储的token
if (to.meta.title) //判断是否有标题 该操作可以再监听路由时候处理 watch:$route(to,from)xxx操作
document.title = to.meta.title

if (to.meta.requireAuth) // 判断该路由是否需要登录权限
if (store.state.token) // 通过vuex state获取当前的token是否存
console.log(有token时候, to, from, next)
next();
else
console.log(没有token时候, to)
next(
path: /login,
query: redirect: to.fullPath // 将跳转的路由path作为参数,登录成功后跳转到该路由
)

else
next();

)

router.afterEach(route =>
//loading加载完成
);

export default router;

vue的接口封装和状态管理_ios

          « ​上一篇: pdf.js使用详解


以上是关于vue的接口封装和状态管理的主要内容,如果未能解决你的问题,请参考以下文章

vue中Axios的封装和API接口的管理

vue中Axios的封装和API接口的管理

vue后台管理系统开发流程全记录_类别管理功能开发: 表单 | 表格 | 分页

vue封装api接口

前端学习(3085):vue+element今日头条管理-封装数据接口

Vue + Element UI:管理应用状态