目录

一.项目全局配置

1. 创建项目

2.底部菜单栏配置tabBar

3.路由配置

4.全局样式配置

5.VUEX配置

6.全局样式配置

7.请求接口封装

二.主要功能实现

1.tabBar导航页面实现,主要页面实现

2.登陆功能实现,token及登陆状态

1.校验判断

2.调用登录接口,存储登陆的用户信息

3.数据缓存,持久化

4.请求拦截器携带token

5.响应拦截器,错误信息提示

6.VUEX刷新后数据丢失处理

7.退出登陆效果

8.用户信息修改

3.登陆功能实现

三.支付功能实现

1.微信

2.支付宝

3.混合支付

四.工具函数封装

1.错误信息提示

2.全局提示信息(文本提示,加载状态)


一.项目全局配置

1. 创建项目

使用Hbuilderx工具创建项目,选择uni-ui项目模版,VUE3

2.底部菜单栏配置tabBar

uniapp官网: 全局文件--pages.json页面路由 -- tabBar

项目文件:pages.json--文件底部添加,list配置2-5

"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#3cc51f",
		"borderStyle": "black",
		"backgroundColor": "#ffffff",
		"list": [{
			"pagePath": "pages/index/index",
			"iconPath": "static/c1.png",
			"selectedIconPath": "static/c2.png",
			"text": "首页"
		}, {
			"pagePath": "pages/index2/index",
			"iconPath": "static/c3.png",
			"selectedIconPath": "static/c4.png",
			"text": "页面"
		}]
	}

注:配置tabBar时所加页面一定要在pages中注册,否则会报错

报错:app.json: "tabBar"["pagePath"]: "pages/index2/index" need in ["pages"]

3.路由配置

app.json文件 -- pages页面配置项

4.全局样式配置

uniapp官网: 全局文件--pages.json页面路由 -- globalStyle

app.json文件 -- globalStyle

5.VUEX配置

store-->index.js

// 页面路径:store/index.js
import { createStore } from 'vuex'

// import moduleA from '@/store/modules/moduleA'

const store = createStore({
	state:{},
	getters: {},
	mutations: {},
	actions: {},
	modules: {
		// moduleA
	}
})

export default store

main.js 文件挂载全局

Vue2/Vue3配置根据文档来修改

6.全局样式配置

uni-scss文件

7.请求接口封装

api -- reuest.js

const http = {
	// baseUrl 地址
	baseUrl: 'http://192.168.0.1:28002',

	// 请求方法
	request(config) {
		// config:请求配置对象,具体参照uniapp文档

		config = beforeRequest(config)

		// 请求地址拼接
		config.url = this.baseUrl + config.url

		// 异步请求
		return new Promise((resolve, reject) => {
			uni.request(config).then(res => { // 成功
				let [error, resp] = res
				// 响应拦截
				const response = beforeResponse(resp)
				resolve(response)
			}).catch(err => { // 失败
				errorHandle(err)
				reject(err)
			})
		})

	},
	get(url, data, auth) {
		/*
		url:接口地址
		data:查询参数
		auth:请求是否携带token进行认证(true/false)
		method:请求方式
		*/
		return this.request({
			url: url,
			data: data,
			auth: auth,
            timeout:10000,
			method: 'GET'
		})
	},
	post(url, data, auth) {
		/*
		url:接口地址
		data:请求体参数
		auth:请求是否携带token进行认证(true/false)
		method:请求方式
		*/
		return this.request({
			url: url,
			data: data,
			auth: auth,
            timeout:10000,
			method: 'POST'
		})
	},
	put(url, data, auth) {
		/*
		url:接口地址
		data:请求体参数
		auth:请求是否携带token进行认证(true/false)
		method:请求方式
		*/
		return this.request({
			url: url,
			data: data,
			auth: auth,
            timeout:10000,
			method: 'PUT'
		})
	},
	delete(url, data, auth) {
		/*
		url:接口地址
		auth:请求是否携带token进行认证(true/false)
		method:请求方式
		*/
		return this.request({
			url: url,
			auth: auth,
            timeout:10000,
			method: 'DELETE'
		})
	}
}

// 请求拦截器
const beforeRequest = (config) => {
	// 请求之前拦截操作
	console.log('请求拦截器', config)
	return config
}

// 响应拦截器
const beforeResponse = (response) => {
	// 请求之后操作
	console.log('响应拦截器', response)
	return response
}

// 请求异常处理器
const errorHandle = ((err) => {
	console.log('请求异常', err)
})

export default http

​ ​api -- index.js

// 封装具体接口调用
import http from 'request.js'
​
export default{
  // 登陆接口
  login(params){
    return http.post('/api/users/login',params)
  }
  // 注册接口
  
  // 刷新token
  
  // 获取用户信息
  
  // 获取信息
}

挂载全局$api方法

// 导入封装的请求对象
import api from '@/api/index.js'
// 将请求对象设置为全局属性
Vue.prototype.$api = api

使用

async fn(){
  const response = await this.$api.login()
}

使用模块,写法用法变化

api -- index.js

// 封装具体接口调用
import http from 'request.js'
​
import user from './modules/user.js'
import goods from './modules/goods.js'
​
export default{
  user,
  goods
}

使用

async fn(){
  const response = await this.$api.user.login()
}

二.主要功能实现

1.tabBar导航页面实现,主要页面实现

2.登陆功能实现,token及登陆状态

uni.login 微信登录

1.校验判断

2.调用登录接口,存储登陆的用户信息

saveLoginInfo(){} 存储登陆信息 存储token和refresh,userInfo ​ isAuth 是否登录

3.数据缓存,持久化

// 数据持久化,存储到缓存中
uni.setStorage({
  key: 'token',
  data: userInfo.token
});
uni.setStorage({
  key: 'isAuth',
  data: isAuth
});
uni.setStorage({
  key: 'refresh',
  data: userInfo.refresh
});
​
// 异步
uni.setStorageSync('token', userInfo.token);

4.请求拦截器携带token

// 请求拦截器
const beforeRequest = (config) => {
  // 请求之前拦截操作
  console.log('请求拦截器', config)
  config.header = {}
  if (config.auth) {
    //  请求头中添加token
    if (uni.getStorageSync('token')) {
      // Authorization    Bearer   根据情况修改
      config.header['Authorization'] = 'Bearer' + uni.getStorageSync('token')
    } else {
      // 为登陆则跳转登陆 重定向
      uni.navigateTo({
        url: '/pages/index/index'
      })
    }
​
  }
  return config
}

5.响应拦截器,错误信息提示

// 响应拦截器
const beforeResponse = (response) => {
  // 请求之后操作
  console.log('响应拦截器', response)
  // 判断请求返回的状态码
  if(response.status !== 200 && response.status !== 201 && response.status !== 204){
    // 给出对应的提示
    if(response.data.error){
      uni.showToast({
        title:response.data.error.toString(),
        icon:'none',
        duration:2000
      })
    }
  }
  return response
}

6.VUEX刷新后数据丢失处理

App.vue ,根据需求更改

<script>
  import {mapMutations} from 'vuex'
  export default {
    onLaunch: function() {
      console.warn('当前组件仅支持 uni_modules 目录结构 ,请升级 HBuilderX 到 3.1.0 版本以上!')
      console.log('App Launch')
    },
    onShow: function() {
      console.log('App Show')
      
      // 读取本地缓存,存储到VUEX中
      uni.getStorageSync('userInfo')
      
      // 调用保存登陆信息 操作
      // 存储相应的token,isAuth,userInfo等数据
    },
    onHide: function() {
      console.log('App Hide')
    },
    methods:{
      ...mapMutations(['保存登陆信息'])
    }
  }
</script>

7.退出登陆效果

将登录时存储的数据清空,跳转相应的登陆页面或者首页

8.用户信息修改

调用相应的修改接口,拿到成功状态后更新VUEX用户信息及本地Storage存储的用户信息

3.登陆功能实现

// 这里是vue2的写法,需要vue3请自行更换
// 获取用户信息
getWXCode() {
	return new Promise((ress, rej) => {
        // wx.login()
		uni.login({
			success: (res) => {
				res.code && ress(res.code)
			},
			fail: (error) => {}
		})
	})
},

//等三方微信登录 信息补充
// 兑换code
// 初始化 获取code 凭证
wxLogin() {
	if (!this.checked) {
		// 是否勾选
		this.$utils.toast(0, '请先阅读并同意服务协议和隐私政策!')
		return
	}
				
	this.$utils.toast(1, "加载中")
	let that = this
	//#ifdef H5
	// #endif
	//#ifdef MP-WEIXIN
	this.getWXCode().then(res => {
	    console.log("getWXCode", res)
        //成功后可根据实际情况自行处理
        // 判断用户是否注册,存储用户数据...
	})
	// #endif
},

三.支付功能实现

1.微信

// 此块代码放在vuex中(store.js)
// 支付接口
		pay({
			commit
		}, param) {
			// console.log("param", param)
			return new Promise((resolve, reject) => {
				$utils.toast(1, "支付中")

				//#ifdef MP-WEIXIN
				const payParam = {
					appId: param.appId,
					nonceStr: param.nonceStr,
					package: param.packageVal,
					timeStamp: param.timeStamp,
					signType: param.signType,
					paySign: param.paySign,
				}
				//#endif
				//#ifdef MP-WEIXIN
				// console.log('MP-WEIXIN')
				uni.requestPayment({
					provider: 'wxpay',
					...payParam,
					success: function(res) {
						console.log("支付成功---", res)
						// $utils.toast(1, "支付成功")
						setTimeout(() => {
							// $utils.toast(2)
							resolve(res)
						}, 1000)
					},
					fail: function(res) {
						console.log("支付失败---", res)
						// $utils.toast(0, "支付失败")
						resolve(res)
					},
					complete: function(res) {
						console.log("支付过程结束", res)
						// resolve(res)
					}
				});
				//#endif
				//#ifndef MP-WEIXIN
				WeixinJSBridge.invoke('getBrandWCPayRequest', {
					"appId": param.appId, //公众号名称,由商户传入
					"timeStamp": param.timeStamp, //时间戳
					"nonceStr": param.nonceStr, //随机串
					"package": param.package, //扩展包
					"signType": param.signType, //微信签名方式:MD5
					"paySign": param.paySign //微信签名
				}, function(respay) {
					// console.log('res', respay)
					if (respay.err_msg === "get_brand_wcpay_request:ok") {
						// 支付完成 
						uni.showToast({
							title: "支付成功",
							icon: "none",
							duration: 2000
						})
						callback()
					} else if (respay.err_msg === "get_brand_wcpay_request:cancel") {
						$utils.toast(0, "取消支付")
					} else if (respay.err_msg === "get_brand_wcpay_request:fail") {
						$utils.toast(0, "支付失败")
					}
				}, function(err) {
					$utils.toast(0, err)
				})
				//#endif
			})
		}

2.支付宝

3.混合支付

四.工具函数封装

注:不全!需要其他的请自行搜索!

1.错误信息提示

注:根据后台需要提示接口错误还是前端自行提示!

// 接口返回提示
	requestCodeTips(code, msg) {
		let errorrMessage = ''
		switch (Number(code)) {
			case 400:
				errorrMessage = '错误请求'
				break;
			case 401:
				errorrMessage = '未授权,请重新登录'
				break;
			case 403:
				errorrMessage = '拒绝访问'
				break;
			case 404:
				errorrMessage = '请求错误,未找到该资源'
				break;
			case 405:
				errorrMessage = '请求方法未允许'
				break;
			case 408:
				errorrMessage = '请求超时'
				break;
			case 500:
				errorrMessage = '服务器端出错啦'
				break;
			case 501:
				errorrMessage = '网络未实现'
				break;
			case 502:
				errorrMessage = '网络错误'
				break;
			case 503:
				errorrMessage = '服务不可用'
				break;
			case 504:
				errorrMessage = '网络超时'
				break;
			case 505:
				errorrMessage = 'http版本不支持该请求'
				break;
			default:
				errorrMessage = '连接错误'
		}

		this.toast(0, `${code}-${errorrMessage}-${msg?msg:''}`)
	},

2.全局提示信息(文本提示,加载状态)

data: {
		msg: null, // 消息提示
		time: 300, // 时间
		hideLoadTimes: null, // 清除加载中的定时器
		showToastTimes: null, // 提示框的定时器
	},

/**
	 * *  提示信息
	 * state: 类型 (0 提示框  1 showLoading  2 hideLoading )
	 * title: 标题
	 * duration: 时间
	 * icon: 图标
	 */
	async toast(state = 0, title = '', duration = 3000, icon = "none") {
		let errMsg = this.data.msg ? this.data.msg.errMsg : null

		if (state == 0) { //
			// 隐藏加载中的定时器还在 
			if (this.data.hideLoadTimes || errMsg == 'showLoading:ok') {
				// 延后显示
				clearTimeout(this.data.showToastTimes)
				this.data.showToastTimes = setTimeout(async () => {
					this.data.msg = await uni.showToast({
						icon,
						title,
						duration,
					});
					this.data.showToastTimes = null
				}, this.data.time + 200)
			} else { // 隐藏加载中的定时器不能存在
				this.data.msg = await uni.showToast({
					icon,
					title,
					duration,
				});
			}
		} else if (state == 1) {
			this.data.time = this.data.time >= 900 ? 900 : this.data.time + 300
			this.data.msg = await uni.showLoading({
				title,
				mask: true
			});
		} else if (state == 2) {
			clearTimeout(this.data.hideLoadTimes)
			this.data.hideLoadTimes = setTimeout(async () => {
				this.data.msg = await uni.hideLoading();
				this.data.time = 300
				this.data.msg = null //
				this.data.hideLoadTimes = null
			}, this.data.time)
		}
	},

注:内容不全,哪部分缺少的话需要大佬们自行查询!谨慎食用哦!!!

相关文章:

1.前端环境变量配置

2.Axios封装_axios cdn链接

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐