小程序的数据需要向后端发请求进行获取,为了简化后续的开发,需要创建一个包专门存放所有发请求的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
}
}
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) => {
if (result.statusCode != 200) {
return rej();
}
let data = result.data;
res(data);
}
})
})
}
}
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
})
}
<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() {
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))
if (res.code != 200) {
this.$refs.uToast.show({
type: 'error',
message: res.msg
})
} else {
// 存储token
uni.setStorage({
key: "token",
data: res.token,
success: (res) => {
// 跳转到首页
uni.reLaunch({
url: "/pages/index/index"
})
}
})
}
})
}).catch(errors => {
this.$refs.uToast.show({
type: 'error',
message: "表单数据校验失败,请检查后再登录"
})
})
}
}
}
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"
})