# 注册登录

# 技术点

code 登录 登录信息存入全局 验证码输入框 找回密码流程 短信发送倒计时

# 目录结构

└─ pages
   └─ account                    # 账号相关
      ├─ components
      │  └─ captcha-modal        # 图片验证码
      ├─ login                   # 账号登录
      ├─ register                # 账号注册
      └─ forget                  # 忘记密码

提示

本项目中账号注册与找回密码,均使用短信验证码方式进行校验。

# 注册

流程:输入手机号->点击发送验证码->输入图形验证码->后端校验成功->后端发送验证码->手机接收验证码并填入->注册->手机验证码校验成功->后端返回 token ->登录成功

# 倒计时

methods: {
	// 倒计时,计时器时间需要写入本地存储,防止用户刷新后重新计时
	doLoop() {
		this.setData({
			second: --this.data.second
		})

		wx.setStorageSync("second", this.data.second);

		if (this.data.second > 0) {
			this.setData({
				codeText: this.data.second + " s"
			})
		} else {
			clearInterval(this.data.clock); //清除js定时器
			this.setData({
				sendWaiting: false,
				codeText: "获取验证码",
				second: 120, //重置时间
			})
		}
	}
}

# 登录

# 账号密码登录

登录流程较为简单,用户输入账号密码后,前端会携带上通过 wx.login 获取到的 code, 后端通过微信提供的接口换取当前用户的 openid ,并将 openid 与该用户账号绑定,使下次进入小程序时能够自动登录。
登录成功后的信息也会存入 app.js 中。

// 引入登录相关接口,微信限制,只能使用相对路径
import { getUserToken, getUserInfo } from "../../../api/user"
const app = getApp()

Page({

	data: {
		code: "",
		account: "",
		password: ""
	},

	methods: {
		doLogin() {
			// 获取 code
			wx.login({
				success: ({ code }) => {
					this.data.code = code;
				},
				complete: () => {
					this.getUserToken();
				}
			})
		},

		// 登录
		async getUserToken() {
			const { account, password } = this.data;

			let params = {
				account,
				password,
				type: 'minip',
				code: this.data.code
			}

			// 获取鉴权 token
			const loginRes = await getUserToken(params);

			wx.setStorageSync('token', loginRes.data.token);

			// 获取当前登录用户信息
			const userRes = await getUserInfo();

			// 登录成功
			if (userRes.code === 200) {

				// 将用户信息存入 `app.js`
				app.user = userRes.data

				wx.navigateBack()
			}
		}
	}
}}
methods: {
	// 用户登录
	doLogin() {
		// ... 以上省略账号密码等前端校验
		try {
			// 执行 vuex 中的用户登录方法
			const loginRes = await this.$store.dispatch("user/login", this.form);

			if (loginRes.code !== 200) {
				this.loading = false;
				this.$toast(loginRes.message);
				return;
			}

			// 执行 vuex 中的获取用户信息方法
			const userRes = await this.$store.dispatch("user/getInfo");
			this.loading = false;

			// 登录成功
			if (userRes.code === 200) {
				this.$toast("登录成功");
				sessionStorage.setItem("account", this.form.account);

				// 如果是从其它需要登录权限的页面进入到登录页面,
				// 登录成功后则重定向到该页面,否则跳转到首页
				this.$router.replace(this.$route.query.redirect || "/home");
			}
		} catch (e) {
			this.loading = false;
		}
	}
}

# 自动登录

app.js 中,通过 wx.login 方法获取 code ,将 code 传给后端,后端通过接口获取对应 openid ,如果该 openid 与已有账号绑定过,则直接返回 token ,用户可自动登录。

App({
  async onLaunch() {
		wx.login({
			success: async ({ code }) => {
				const params = {
					code,
					type: 'minip'
				}
				const loginRes = await getUserTokenByCode(params);

				// 如果未获取到 `token` (code 过期、未绑定过等情况时,则不用再调用以下获取用户信息接口)
				if (loginRes.code !== 200) return;

				wx.setStorageSync('token', loginRes.data.token)

				const userRes = await getUserInfo();

				// 登录成功
				if (userRes.code === 200) {
					this.user = userRes.data
				}
			}
		})
	}
})

# 找回密码

流程:输入手机号->校验存在->获取手机验证码->输入图形验证码->后端校验成功->发送手机验证码->输入手机验证码->后端校验成功->输入新密码->完成->重新登录

# 图片验证码

如下图所示,在点击验证码时,会出现一个弹窗,上部分的图形验证码是由后端生成的base64图片,通过接口获取;下半部分为4个短横线作为输入框内容区。
image.png

# 输入框实现方式

四个短横线并非输入框,只是四个 view 元素做出的展示样式,真正的输入框为覆盖在这四个短横线上的一个绝对定位的透明背景 input 输入框。
image.png

# 核心代码

图形验证码输入框

<view class="code-input-main">
	<!-- 输入验证码展示区 -->
	<view class="code-input-main-item" wx:for="{{codeList}}" wx:key="index">
		{{ code[index] || "" }}
	</view>

	<!-- 验证码实际输入框 -->
	<input class="code-input" bindinput="inputChange" value="{{code}}" focus="{{isFocus}}" maxlength="{{codeLength}}"
		type="tel" />
</view>
上次更新: 2022-10-25 9:05:36 ├F10: PM┤