vuex与axios的优化写法
封装方法
import request from 'axios';import request from '@utils/http';
// 替换模板字符串
function replaceTemplate(template, context) {
if (!context) return template;
return template.replace(
/{(.*?)}/g,
(match, key) => context[key.trim()] || ''
);
}
// cacheUtil
function getParseItem(key) {
try {
const cache = sessionStorage.getItem(`config_${key}`);
return JSON.parse(cache);
} catch (e) {
return null;
}
}
function setParseItem(key, value) {
if (key && value) {
sessionStorage.setItem(`config_${key}`, JSON.stringify(value));
}
}
const cacheUtil = {
getParseItem,
setParseItem
};
function convertObj(data) {
const _result = [];
for (const key in data) {
const value = data[key];
if (value.constructor === Array) {
value.forEach(function(_value) {
_result.push(key + '=' + _value);
});
} else {
_result.push(key + '=' + value);
}
}
return _result.join('&');
}
/*
exp: var obj1 = { a: { name: 'a-1', headers: { token: '1', cookie: '2' } }, b: 'b', c: 'c' }
var obj2= { a: { name: '1-2', headers: { token: '2', oppenid: 'oppenid' } } }
JSON.stringify(deepMerge(obj1, obj2), null, 2)
"{
"a": {
"name": "1-2",
"headers": {
"token": "2",
"cookie": "2",
"oppenid": "oppenid"
}
},
"b": "b",
"c": "c"
}"
*/
function deepMerge(obj1, obj2) {
let key;
for (key in obj2) {
// 如果target(也就是obj1[key])存在,且是对象的话再去调用deepMerge,否则就是obj1[key]里面没这个对象,需要与obj2[key]合并
obj1[key] =
obj1[key] && obj1[key].toString() === '[object Object]'
? deepMerge(obj1[key], obj2[key])
: (obj1[key] = obj2[key]);
}
return obj1;
}
/**
* 制造请求action
* @param method 请求方法: get(默认), post, put等
* @param type mutation类型
* @param url 请求url
* @param defaultQuery 默认参数
* @param useCache 是否使用缓存
* @param resolve 回调函数(可处理数据)
* @returns function
*/
function makeAction(
{ method = 'get', type, url, query = {}, params = {}, useCache, config = {} },
resolve
) {
const defaultConfig = JSON.parse(JSON.stringify(config));
const defaultQuery = JSON.parse(JSON.stringify(query));
const defaultParams = JSON.parse(JSON.stringify(params));
/**
* @param pathData 替换url模板的数据
* @param query get, delete请求上传数据
* @param params post, put请求上传数据
* @param isCommit 是否调用vuex.commit方法
* @param isloading headers是否添加loading标识(X-Requested-loading)
*/
return (
{ commit },
{
pathData,
query,
params,
isCommit = true,
config = {},
isloading = false,
isLoading = false
} = {}
) => {
let body = {};
let requestArgs = [];
isloading = isloading || isLoading; // 防止大小写弄混
config = deepMerge(defaultConfig, config);
if (!config.headers) {
config.headers = {};
}
if (isloading) {
config.headers['X-Requested-loading'] = isloading;
}
if (!Array.isArray(query)) {
query = { ...defaultQuery, ...query };
}
if (!Array.isArray(params)) {
params = { ...defaultParams, ...params };
}
// get参数特殊处理
if (method === 'get' || method === 'delete') {
body = {
params: query
};
config.params = query;
requestArgs = [config];
} else {
body = params;
requestArgs = [body, config];
}
// 使用缓存
const cacheKey = `${method}_${url}_${JSON.stringify(body)}`;
if (useCache) {
const resData = cacheUtil.getParseItem(cacheKey);
if (resData) {
resolve && resolve(resData);
type && isCommit && commit(type, resData.data);
return Promise.resolve(resData);
}
}
let url2 = url;
// 当post 和Put 需要添加Url参数时
if (
['post', 'put'].includes(method) &&
query &&
Object.keys(query).length
) {
if (url.indexOf('?') === -1) {
url2 += '?' + convertObj(query || {});
} else {
url2 += '&' + convertObj(query || {});
}
}
// 请求
return request[method](
replaceTemplate(url2, pathData),
...requestArgs
).then((resData = {}) => {
// 使用缓存
if (useCache) {
Object.keys(resData).length &&
cacheUtil.setParseItem(cacheKey, resData);
}
resolve && resolve(resData);
type && isCommit && commit(type, resData.data);
return Promise.resolve(resData);
});
};
}
export default makeAction;
使用方法
vuex:
action.js
- get
getData: makeAction({
type: types.GET_DATA,
url: 'get/{id}?a=1',
}),
- post
addData: makeAction({
method: 'post',
url: '/add/{id}?key=value',
}),
- put
updataData: makeAction({
method: 'put',
url: 'updata/{id}',
}),
- delete
deleteData: makeAction({
method: 'delete',
url: 'delete/{id}',
}),
mutaions.js
[types.GET_DATA] (state, data) {
state.data= data || [];
},
page:
computed: {
...mapState([
'data',
]),
},
methods: {
...mapActions([
'getData',
'addData',
]),
},
mounted() {
this.getData({
pathData: {
id: '1'
},
query: { // search
key1: 'value1',
key2: 'value2',
},
params: { // bodyData (post)
key1: ''key1
},
isCommit: false //是否commit
})
}
网友评论