说明

项目基于若依管理系统进行开发,部分接口来源于若依管理系统后端项目,如本文的登录接口、获取验证码接口。

请求包创建

小程序的数据需要向后端发请求进行获取,为了简化后续的开发,需要创建一个包专门存放所有发请求的js方法。

创建文件夹

创建api的存放包
在这里插入图片描述
再创建工具js的存放包
在这里插入图片描述

请求工具request.js

注意使用该文件,请修改baseUrl对应的值,配置好你的后端的请求Ip和端口。

export default {
	common: {
		baseUrl: 'http://localhost:8085',
		// 如果需要真机调试,打开cmd使用ipconfig命令,这样手机才可以在同一局域网访问到后端
		// baseUrl: 'http://10.23.12.180:6001',
		data: {},
		header: {},
		method: "GET",
		dataTyoe: 'json'
	},
	/**
	 * 请求拦截器
	 */
	request(options = {}) {
		let token = uni.getStorageSync('token')
		if (token) {
			this.common.header = {
				'token': token,
				// 若依管理系统后端识别的是这个
				'Authorization': token
			}
		}
		options.url = this.common.baseUrl + options.url;
		options.data = options.data || this.common.data;
		options.header = options.header || this.common.header;
		options.method = options.method || this.common.method;
		options.dataTyoe = options.dataTyoe || this.common.dataTyoe;
		return new Promise((res, rej) => {
			uni.request({
				...options,
				success: (result) => {
					// console.log("请求响应:" + JSON.stringify(result));
					let data = result.data;
					if (data.code != 200) {
						// 报错提示
						// uni.showToast({
						// 	title: data.msg,
						// 	icon: 'none',
						// 	duration: 2000
						// })
						if (data.code == 401) {
							console.log("跳转到登录页")
							// 清除掉token,因为token在后端已经过期
							uni.clearStorage();
							uni.reLaunch({
								url: "/pages/login/login"
							})
						} else {
							// catch可以接收data
							return rej(data);
						}
					}
					// then可以接收data
					res(data);
				}
			})
		})
	},

}

关于下面所示的代码,需要根据你的后端来修改,例如你的响应码不一定叫code,你的信息也不一定叫做msg,请求成功的状态码不一定是200,登录的token失效的状态码不一定是401,需要改成自己的

success: (result) => {
// console.log("请求响应:" + JSON.stringify(result));
	let data = result.data;
	if (data.code != 200) {
		// 报错提示
		// uni.showToast({
		// 	title: data.msg,
		// 	icon: 'none',
		// 	duration: 2000
		// })
		if (data.code == 401) {
			console.log("跳转到登录页")
			// 清除掉token,因为token在后端已经过期
			uni.clearStorage();
			uni.reLaunch({
				url: "/pages/login/login"
			})
		} else {
			// catch可以接收data
			return rej(data);
		}
	}
	// then可以接收data
	res(data);
}

登录功能实现

请求方法

创建login.js文件
在这里插入图片描述

import httpRequest from '@/utils/request'

// 登录方法
export function login(username, password, code, uuid) {
  const data = {
    username,
    password,
    code,
    uuid
  }
  return httpRequest.request({
    url: '/login',
    headers: {
      isToken: false
    },
    method: 'post',
    data: data
  })
}

// 获取验证码
export function getCodeImg() {
  return httpRequest.request({
    url: '/captchaImage',
    headers: {
      isToken: false
    },
    method: 'get',
    timeout: 20000
  })
}

页面

创建login.vue文件
在这里插入图片描述

<template>
	<view class="login">
		<u-toast ref="uToast"></u-toast>
		<view class="form">
			<view class="title">
				<text>易售二手平台</text>
			</view>
			<u--form labelPosition="left" :model="model" :rules="rules" ref="loginForm">
				<u-form-item prop="loginForm.username" leftIcon="account-fill" borderBottom ref="item1">
					<view class="item">
						<u--input v-model="model.loginForm.username" border="none"></u--input>
					</view>
				</u-form-item>
				<u-form-item prop="loginForm.password" leftIcon="lock-fill" borderBottom ref="item1">
					<view class="item">
						<u--input v-model="model.loginForm.password" password border="none"></u--input>
					</view>
				</u-form-item>
				<u-form-item prop="loginForm.code" leftIcon="integral-fill" borderBottom ref="item1">
					<view class="item">
						<u-input v-model="model.loginForm.code" clearable border placeholder="验证码"></u-input>
						<img :src="codeUrl" @click="getCode" class="login-code-img" />
					</view>
				</u-form-item>
			</u--form>

			<view style="margin-top: 20rpx;">

			</view>

			<u-button type="primary" class="login-button" @click="login()">登录</u-button>
		</view>

	</view>
</template>

<script>
	import {
		getCodeImg,
		login
	} from "@/api/login";

	export default {
		data() {
			return {
				model: {
					loginForm: {
						username: 'admin',
						password: 'admin123',
						uuid: '',
						code: '',
					},
				},
				// 登录表单字段校验过程
				rules: {
					'loginForm.username': {
						type: 'string',
						required: true,
						message: '请填写用户名',
						trigger: ['blur', 'change']
					},
					'loginForm.password': {
						type: 'string',
						required: true,
						message: '请填写密码',
						trigger: ['blur', 'change']
					},
					'loginForm.code': {
						type: 'number',
						required: true,
						message: '请输入数字类型的验证码',
						trigger: ['blur', 'change']
					},
				},
				codeUrl: "",
			}
		},
		onReady() {
			//onReady 为uni-app支持的生命周期之一
			this.$refs.loginForm.setRules(this.rules)
		},
		created() {
			let token = uni.getStorageSync('token')
			if (token) {
				this.toIndex();
			}
			this.getCode();
		},
		methods: {
			/**
			 * 获取验证码
			 */
			getCode() {
				// console.log("获取验证码")
				getCodeImg().then(res => {
					// console.log("获取验证码:" + JSON.stringify(res))
					let captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
					if (captchaEnabled) {
						this.codeUrl = "data:image/gif;base64," + res.img;
						this.model.loginForm.uuid = res.uuid;
					}
				});
			},
			login() {
				this.$refs.loginForm.validate().then(res => {
					// console.log("登录:");
					login(this.model.loginForm.username, this.model.loginForm.password, this.model.loginForm.code,
						this.model
						.loginForm.uuid).then(
						res => {
							// console.log("登录:" + JSON.stringify(res))
							// 存储token
							uni.setStorage({
								key: "token",
								data: res.token,
								success: (res) => {
									this.toIndex();
								}
							})
						}).catch(res => {
						this.$refs.uToast.show({
							type: 'error',
							message: res.msg
						})
					})
				}).catch(errors => {
					this.$refs.uToast.show({
						type: 'error',
						message: "表单数据校验失败,请检查后再登录"
					})
				})

			},
			toIndex() {
				// 跳转到首页
				uni.reLaunch({
					url: "/pages/index/index"
				})
			}

		}
	}
</script>

<style lang="scss">
	.login {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		height: 100vh;
		// background: #2b92ff;
		background-color: #0093E9;
		background-image: linear-gradient(135deg, #0093E9 0%, #80D0C7 100%);

		.title {
			width: 100%;
			font-weight: bold;
			font-size: 45rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			margin-bottom: 30rpx;
		}

		.form {
			width: 600rpx;
			background: #ffffff;
			padding: 30rpx;
			border-radius: 20rpx;

			.item {
				display: flex;
				height: 80rpx;
			}

			.login-code-img {
				float: right;
				height: 80rpx;
				width: 160rpx;
				padding-left: 12rpx;
			}

			.login-button {
				margin-top: 50rpx;
				width: 80%;
			}
		}


	}
</style>

在这里插入图片描述

涉及知识点

错误提示

当用户登录时密码或者验证码出错时,需要提示用户登录出错的原因

this.$refs.uToast.show({
	type: 'error',
	message: res.msg
})

在这里插入图片描述

前端校验

现在出错是后端校验的,其实前端也可以做很多校验,在前端不让不合法的输入提交,这样可以减轻后端服务器的压力。如已经验证码为算术题,答案肯定是数字,那就限制用户不能输入字符串。

首先需要定义规则,如下面的代码

rules: {
	'loginForm.username': {
	type: 'string',
		required: true,
		message: '请填写用户名',
		trigger: ['blur', 'change']
	},
	'loginForm.password': {
		type: 'string',
		required: true,
		message: '请填写密码',
		trigger: ['blur', 'change']
	},
	'loginForm.code': {
		type: 'number',
		required: true,
		message: '请输入数字类型的验证码',
		trigger: ['blur', 'change']
	},
},

在页面初始化的时候,给表单设置规则,如下面的代码

onReady() {
	//onReady 为uni-app支持的生命周期之一
	this.$refs.loginForm.setRules(this.rules)
},

最后使用:rules="rules"给表单绑定规则,如下面的代码

<u--form labelPosition="left" :model="model" :rules="rules" ref="loginForm">

在点击登录按钮之后,一定要通过校验之后,才真正向后端发请求

this.$refs.loginForm.validate().then(res => {
   // 校验通过之后,向后端发登录请求
}).catch(errors => {
	this.$refs.uToast.show({
		type: 'error',
		message: "表单数据校验失败,请检查后再登录"
	})
})

当校验不通过时,不会发请求
在这里插入图片描述

设置token到客户端缓存中

当用户登录成功之后,后端给前端返回一个凭证,即token,可以理解为一把钥匙,用户后面访问其他接口的时候,就带上这把钥匙,后端判断用户有钥匙之后,就让用户访问接口。当然,钥匙是有过期时间的,当过期之后,用户就需要重新登录。下面是设置缓存的代码:

uni.setStorage({
	key: "token",
	data: res.token,
	success: (res) => {
		// 跳转到首页
		
	}
})

在这里插入图片描述
在前面的request.js文件中,有这么一段代码,作用就是在发请求之前,从缓存中取出token对应的值,然后放到请求头中,这样后端就可以去请求头中获取token的值

let token = uni.getStorageSync('token')
if (token) {
	this.common.header = {
		'token': token
	}
}

路由跳转

当登录成功之后,需要跳转到小程序首页

// 跳转到首页
uni.reLaunch({
	url: "/pages/index/index"
})

如果已经登录过,访问登录页直接跳转到首页

created() {
	let token = uni.getStorageSync('token')
	if (token) {
		this.toIndex();
	}
	this.getCode();
},

同项目其他文章

该项目的其他文章请查看【易售小程序项目】项目介绍、小程序页面展示与系列文章集合

Logo

快速构建 Web 应用程序

更多推荐