路由跳转踩坑
小程序路由是栈,先进先出,我使用WEB开发思维去进行页面路由跳转频繁使用:
uni.navigateTo
就造成不停返回上一页面,后面我改用了:
uni.redirectTo
关闭当前页面跳转到指定页面又造城栈里面没有内容,返回的时候就退出了小程序,再往后又使用了:
uni.reLaunch
强行跳转,并且清除历史记录,又造城一些交互问题,后面我又在APP.vue中定义了全局路由守卫还是解决不了问题
直到我碰到
scss
uni.navigateBack()
维护好一个栈的良好性保证了好的交互。
路由封装
原本的uniapp路由请求:
javascript
uni.request({
url: 'https://api.example.com/data', // 接口URL
method: 'GET',
data: {
page: 1,
size: 10
},
success: (res) => {
console.log('请求成功', res.data);
},
fail: (err) => {
console.error('请求失败', err);
},
complete: () => {
// 无论成功或失败都会执行
}
});
必然满足不了,具体业务的实现受限url里面内容太多,其次还有请求成功失败不能进行统一提醒很麻烦,还有开发环境和生产环境切换地址也是个问题,基于此需要简单封装下路由请求工具:
javascript
// 配置管理,便于环境切换和统一维护
const CONFIG = {
// 默认使用开发环境配置
environment: 'development',
baseURL: {
development: "https://www.XXXXX.vip",
production: "https://XXXXXXX"
},
appid: "wx5c928b56171b7bf7"
};
// 请求拦截器接口,可注册多个拦截器
const requestInterceptors = [];
// 响应拦截器接口,可注册多个拦截器
const responseInterceptors = [];
/**
* 设置当前环境
* @param {string} env - 环境名称,如 'development' 或 'production'
*/
function setEnvironment(env) {
if (CONFIG.baseURL[env]) {
CONFIG.environment = env;
console.info(`环境已设置为: ${env}`);
} else {
console.error(`无效的环境名称: ${env}`);
}
}
/**
* 注册请求拦截器
* @param {function} interceptor - 拦截器函数,接收配置对象并返回新的配置对象
*/
function registerRequestInterceptor(interceptor) {
requestInterceptors.push(interceptor);
}
/**
* 注册响应拦截器
* @param {function} interceptor - 拦截器函数,接收响应对象并返回新的响应对象
*/
function registerResponseInterceptor(interceptor) {
responseInterceptors.push(interceptor);
}
/**
* 统一的错误处理函数
* @param {object} error - 错误对象
*/
function handleError(error) {
console.error('请求发生错误:', error);
// 这里可以添加统一的错误提示或处理逻辑
uni.showToast({
title: error.message || '请求失败,请稍后重试',
icon: 'none',
duration: 2000
});
// 可以根据错误类型做不同处理
if (error.code === 401) {
// 处理未授权错误,如跳转到登录页
console.log('未授权,需要重新登录');
uni.navigateTo({
url: '/pages/login/login'
});
}
}
/**
* 核心请求函数
* @param {object} options - 请求配置
* @param {string} options.url - 请求URL
* @param {string} [options.method="GET"] - 请求方法
* @param {object} [options.data={}] - 请求数据
* @param {object} [options.header={}] - 请求头
* @returns {Promise} - 返回Promise对象
*/
function request({ url, method = "GET", data = {}, header = {} }) {
return new Promise((resolve, reject) => {
try {
// 从缓存中同步获取 Token
const token = uni.getStorageSync("Token");
// 构建基础请求配置
let config = {
url: `${CONFIG.baseURL[CONFIG.environment]}${url}`,
method,
data,
header: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
appid: CONFIG.appid,
...header
}
};
// 应用请求拦截器
let interceptedConfig = config;
requestInterceptors.forEach(interceptor => {
interceptedConfig = interceptor(interceptedConfig);
});
uni.request({
...interceptedConfig,
success: (res) => {
// 应用响应拦截器
let interceptedResponse = res;
responseInterceptors.forEach(interceptor => {
interceptedResponse = interceptor(interceptedResponse);
});
if (interceptedResponse.statusCode === 200) {
resolve(interceptedResponse.data);
} else {
const error = {
code: interceptedResponse.statusCode,
message: interceptedResponse.data.message || "请求错误,请重试"
};
handleError(error);
reject(error);
}
},
fail: (err) => {
const error = {
code: -1,
message: err.errMsg || "网络请求失败"
};
handleError(error);
reject(error);
}
});
} catch (error) {
const err = {
code: -2,
message: error.message || "请求处理失败"
};
handleError(err);
reject(err);
}
});
}
// 使用 CommonJS 导出
module.exports = {
request
};
生产环境和开发环境进行区分,并且统一处理报错,请求头等信息方便管理