赞
踩
只要创建 uniapp 项目就会有默认配置,但我们都会有解决跨域问题等,所以建好项目配置和封装是必要的。
根目录新建一个 common 文件夹,里边配置 util.js 、 request.js 、 config.js 可按需配置,以下配上内容
/** * 拼接对象为请求字符串 * 对于需要编码的文本(比如说中文)我们要进行编码 * @param {Object} obj - 待拼接的对象 * @returns {string} - 拼接成的请求字符串 **/ export function formatGetUri(obj, Object) { // const params: Array < string >= [] const params = [] Object.keys(obj).forEach((key) => { let value = obj[key] if (typeof value !== 'undefined' || value !== null) { params.push([key, encodeURIComponent(value)].json('=')) } }) return '?' + params.join('&') } //表单序列化 export function convertSerialize(data){ let list = []; Object.keys(data).forEach(ele => { list.push(`${ele}=${data[ele]}`) }) return list.join('&'); }
import {convertSerialize} from './util.js' import store from '../store/index.js' const request = {} const headers = {} request.globalRequest = (url, method, data, power) => { let header = {} /** * 权限判断 */ switch (power) { case 0: headers['Authorization'] = 'Bearer' + uni.getStorageSync('token') // 处理刷新token后重新请求的自定义变量 headers['refresh_token'] = false break case 1: headers['Authorization'] = 'Basic a3N1ZGk6a3N1ZGk=' break; case 2: headers['Authorization'] = 'Basic a3N1ZGlfcGM6a3N1ZGlfcGM=' break; case 3: responseType = 'blob' break; case 4: header = { 'content-type': "application/x-www-form-urlencoded;charset=utf-8" } break; default: break; } //接口公共参数 const obj = { orgId: uni.getStorageSync('orgId') || 0, userId: uni.getStorageSync('userId') || 0, operator: uni.getStorageSync('loginName') || '匿名', timestamp: new Date().getTime() } let JSONParams = { url: url, method: method, data: { ...obj, ...data }, dataType: 'JSON', header: header, } if (power != 4) { JSONParams = { url: url, method: method, data: { ...obj, ...data }, dataType: 'JSON', header: headers, } } return uni.request(JSONParams).then(res => { if (res[1]) { //TODO 根据实际后台返回格式修改 if (res[1].statusCode == 200) { // #ifdef H5 return res[1].data // #endif // #ifdef MP-WEIXIN return JSON.parse(res[1].data) // #endif // #ifdef APP-PLUS return res[1].data // #endif } else if (res[1].statusCode == 401 && !headers.refresh_token) { //接口返回401时认证 续签 const {url, method, data} = JSONParams headers.refresh_token = true return store.dispatch('refreshToken').then(res=>{ uni.setStorageSync('token',res) return request.globalRequest(url, method, data, 0) }) } else if (res[1].statusCode == 403) { //接口返回403时token过期权限不足,故重登 uni.redirectTo({ url: '/pages/public/login' }) } else { //抛出异常 throw res[1].data } } }).catch(params => { switch (params.code) { case 401: uni.clearStorageSync() break default: uni.showToast({ title: params.message, icon: 'none' }) return Promise.reject() break } }) } export default request
此处用到续签,顺便加上这个功能,不需要时可删除,拦截器拦截401前需在 store 入口文件添加操作,place look
import Vue from 'vue' import Vuex from 'vuex' import api from '../api/index.js' Vue.use(Vuex) const store = new Vuex.Store({ state: {}, actions: { async refreshToken(store) { let token = uni.getStorageSync('token') let refresh_Token = uni.getStorageSync('refreshToken') let params = { access_token: token, refresh_token: refresh_Token, grant_type: 'refresh_token', client_id: 'flying', client_secret: 'yaohw', } //登录 let newToken = await api.user.login(params) return newToken.value } } }) export default store
let UAC_URL = "" let DT_WB_URL = "" //默认路径应与 manifest.json 一致,同时修改 let DEFAULT_UAC_URL = "http://192.168.0.125:9101" let DEFAULT_DT_WB_URL = "http://192.168.0.125:9102" if (process.env.NODE_ENV === 'development') { // #ifdef H5 UAC_URL = '/uac' DT_WB_URL = '/lift' // #endif // #ifdef MP-WEIXIN UAC_URL = DEFAULT_UAC_URL DT_WB_URL = DEFAULT_DT_WB_URL // #endif // #ifdef APP-PLUS UAC_URL = DEFAULT_UAC_URL DT_WB_URL = DEFAULT_DT_WB_URL // #endif } else { UAC_URL = DEFAULT_UAC_URL DT_WB_URL = DEFAULT_DT_WB_URL } export default { UAC_URL, DT_WB_URL }
{ "h5" : { //实现跨域访问 "devServer" : { "port" : 9200, //本机端口 "disableHostCheck" : true, "proxy" : { //访问的ip及端口,可有多个 "/uac" : { "target" : "http://192.168.0.125:9101/", "changeOrigin" : true, "secure" : false, "pathRewrite" : { "^/uac" : "/" } }, "/lift" : { "target" : "http://192.168.0.125:9102/", "changeOrigin" : true, "secure" : false, "pathRewrite" : { "^/lift" : "/" } } } } } }
目录安排:
api —— index.js文件、modules文件夹
modules —— js文件(请求接口)
import user from './modules/user.js'
import home from './modules/home.js'
import order from './modules/order.js'
const api = {
user,
home,
order
}
export default api
import request from '@/common/request.js'
import config from '@/common/config.js'
import {
formatGetUri
} from '@/common/util.js'
const uac = config.UAC_URL
const lift = config.DT_WB_URL
const user = {}
//轮播图
user.banners = () => request.globalRequest(lift + "/anon/banner/app/valid", 'POST', null, 0)
export default user
import Vue from 'vue' import App from './App' import api from 'api/index.js' import url from './common/config.js' Vue.config.productionTip = false Vue.prototype.$fire = new Vue(); Vue.prototype.$api = { api }; Vue.prototype.$url = url; App.mpType = 'app' const app = new Vue({ ...App }) app.$mount()
//轮播图,接口已在user.js定义
banners() {
this.$api.api.user.banners().then(res => {
if (res.result.code == '000000') {
this.carouselList = res.body
} else if (res.result.code == '999999') {
this.$u.toast('丫,网络开小差了')
} else {
this.$u.toast(res);
}
})
},
到此为止,一个简单的框架就算完成了,还附带了接口请求及调用、token过期重登及续签,希望整理的还算清楚