很多时候我们并不需要用到微信自带的帐号登录,而是请求到我们自己请求的接口,很多新手对这个流程开发并不熟悉,我会系统写出一个工程化的登录功能。
先从创建项目开始吧
AppID可以不加,我顺手加上了。
pages -> 新建文件夹 (login) -> 新建Page (login)
检查 app.json
是否有该页面注入
编写基本的页面和 CSS 样式
在写 css 之前,我们先把默认自带的样式删掉,以免造成影响和干扰。
app.wxss
清空内容。
<view class="container">
<view class="wrapper">
<view class="left-top-sign">LOGIN</view>
<view class="welcome">
欢迎回来!
</view>
<view class="input-content">
<view class="input-item">
<text class="tit">手机号码</text>
<input type="text" placeholder="请输入手机号码" id="phone" />
</view>
<view class="input-item">
<text class="tit">密码</text>
<input type="password" placeholder="请输入密码" id="password" />
</view>
</view>
<button class="confirm-btn" >登录</button>
<view class="forget-section">
忘记密码?
</view>
</view>
<view class="register-section">
还没有账号?
<text>马上注册</text>
</view>
</view>
page{
height: 100%;
}
.wrapper{
position:relative;
z-index: 90;
padding-bottom: 40rpx;
}
.left-top-sign{
font-size: 120rpx;
color: #f8f8f8;
position:relative;
left: -16rpx;
}
.welcome{
position:relative;
left: 50rpx;
top: -90rpx;
font-size: 46rpx;
color: #555;
}
.input-content{
padding: 0 60rpx;
}
.input-item{
display:flex;
flex-direction: column;
align-items:flex-start;
justify-content: center;
padding: 0 30rpx;
background:#f8f6fc;
height: 120rpx;
border-radius: 4px;
margin-bottom: 50rpx;
}
.input-item:last-child{
margin-bottom: 0;
}
.input-item .tit{
height: 50rpx;
line-height: 56rpx;
font-size: 30rpx;
color: #606266;
}
.input-item input{
height: 60rpx;
font-size: 30rpx;
color: #303133;
width: 100%;
}
.confirm-btn{
width: 630rpx!important;
height: 76rpx;
line-height: 76rpx;
border-radius: 50rpx;
margin-top: 70rpx;
background: #d43c33;
color: #fff;
font-size: 32rpx;
padding: 0;
}
.confirm-btn2:after{
border-radius: 100px;
}
.forget-section{
font-size: 28rpx;
color: #4399fc;
text-align: center;
margin-top: 40rpx;
}
.register-section{
position:absolute;
left: 0;
bottom: 50rpx;
width: 100%;
font-size: 28rpx;
color: #606266;
text-align: center;
}
.register-section text{
color: #4399fc;
margin-left: 10rpx;
}
添加新的编译模式,访问到登录页面
页面如下
首先对 手机号码 和 密码 两个输入框进行监听和保存
我们可以在 input
标签中添加 bindinput=“function()”
修改代码如下
<input type="text" placeholder="请输入手机号码" id="phone" bindinput="inputMsg" />
<input type="password" placeholder="请输入密码" id="password" bindinput="inputMsg" />
在 login.js
写出 inputMsg()
方法
/**
* 监听输入
* @param {*} event
*/
inputMsg(event){
console.log(event);
}
每次在输入框输入时,都会去触发该方法,并且带有参数,该参数(event)的 event.detail.value
值正是我们输入的最新内容,同时 event.currentTarget.id
是我们输入框设置的 id,正好可以用来区分 手机号码 和 密码。
因此我们可以在该方法中,实时将内容保存到我们的 data 数据中
data: {
phone: '',
password: ''
},
/**
* 监听输入
* @param {*} event
*/
inputMsg(event){
let type = event.currentTarget.id;
this.setData({
[type]: event.detail.value
})
},
setData()
中的 type
需要加 []
,将其作为一个变量,实时更新 data
对应的数据。
接下来为登录按钮添加方法,同时提高用户体验,在密码输入框按回车进行登录也是有必要的。
<input type="password" placeholder="请输入密码" id="password" bindinput="inputMsg" bindconfirm="toLogin" />
<button class="confirm-btn" bindtap="toLogin">登录</button>
编写 toLogin()
方法,我仅写出最简单的登录请求和简陋的返回值处理。
/**
* 登录
*/
toLogin() {
let {
phone,
password
} = this.data;
// 调用后端登录接口
wx.request({
url: 'http://localhost:3000/login/cellphone',
method: 'POST',
data: {
phone,
password
},
success: (result) => {
if (result.data.code === 200) {
wx.showToast({
title: '登录成功',
})
// 将用户的信息存储到本地
wx.setStorageSync('userInfo', JSON.stringify(result));
// 跳转,例如首页
wx.reLaunch({
url: '/pages/index/index',
})
} else if (result.data.code === 400 || result.data.code === 502) {
wx.showToast({
title: '手机号或密码错误',
icon: 'none'
})
} else {
wx.showToast({
title: '登录失败,请与管理员联系',
icon: 'none'
})
}
}
})
}
你可以在请求之前添加一些校验,例如 空校验,格式校验等。
if (!phone) {
wx.showToast({
title: '手机号不能为空',
icon: 'none'
})
return;
}
let phoneReg = /^[1](([3][0-9])|([4][5-9])|([5][0-3,5-9])|([6][5,6])|([7][0-8])|([8][0-9])|([9][1,8,9]))[0-9]{8}$/;
if (!phoneReg.test(phone)) {
wx.showToast({
title: '手机号格式不正确',
icon: 'none'
})
return;
}
if (!password) {
wx.showToast({
title: '密码不能为空',
icon: 'none'
})
return;
}
当你看到这样一个请求这样呈现在代码中,简直是不合理的。常规情况下登录之后每次访问 api资源都是需要携带一些头部校验信息的,因此我们必须要对其进行封装处理。
在 utils 下的 新建一个 request.js
理想的情况下是将 wx.request 封装,减少调用时的代码量,其中有一个问题是 wx.request
是异步请求,是拿不到返回值的,所以我们需要用到 Promise
,最后由于后台返回的数据在 response.data
中, 所以在这里直接返回 data 即可。
export default (url, data = {}, method = 'GET') => {
return new Promise((resolve, reject) => {
wx.request({
url,
data,
method,
header: {
cookie: wx.getStorageSync('cookies') ? wx.getStorageSync('cookies') : ''
},
success: (res) => {
if (data.isLogin) { // 登录请求
// 将用户的cookie存入本地
wx.setStorage({
key: 'cookies',
data: res.cookies,
})
}
resolve(res.data)
},
fail: (err) => {
// console.log('请求失败', err)
reject(err)
}
})
})
}
此时的封装还并非完美,还得将url 中的 ip地址/域名地址 抽离封装到单独的文件中。
新建 config文件夹 -> 新建config.js
// 配置服务器地址
export default {
host: 'http://localhost:3000'
}
在 request.js
引入并调用
import config from '../config/config.js'
url: config.host + url
在 login.js
引入并使用
import request from '../../utils/request'
toLogin() {
let {
phone,
password
} = this.data;
// 调用后端登录接口
let result = await request('/login/cellphone', {
phone,
password
});
if (result.code === 200) {
wx.showToast({
title: '登录成功',
})
// 将用户的信息存储到本地
wx.setStorageSync('userInfo', JSON.stringify(result));
// 跳转,例如首页
wx.reLaunch({
url: '/pages/index/index',
})
} else if (result.code === 400 || result.code === 502) {
wx.showToast({
title: '手机号或密码错误',
icon: 'none'
})
} else {
wx.showToast({
title: '登录失败,请与管理员联系。',
icon: 'none'
})
}
},
一个简单的登录就开发完成了。
版权属于:乐心湖's Blog
本文链接:https://cloud.tencent.com/developer/article/1774969
声明:博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!