uni-app: Realize account and password login, and realize that when the page has logged in to the account, there is no need to enter the account password when logging in next time (local cache implementation)

Effect

front-end code

1. Complete code

<template>
	<view>
		<view class="all">
			<view class="title">
				<image :src="title_login" alt="图片损坏" />
			</view>
			<form class="login-form" @submit="formSubmit">
				<view class="input-group ">
					<text class="input-label">帐号</text>
					<input binf cursor-spacing="30" id="userid" maxlength="18" placeholder="请输入用户名" data-type="Idnumber"
						name='zhanghao' />
				</view>
				<view class="input-group password">
					<text class="input-label">密码</text>
					<input :password='isShowPassword' class="mima" name='mima' cursor-spacing="30" id="passwd"
						placeholder="请输入6位及其以上字符" data-type="password" maxlength="20" />
					<view class="eye_position" @tap='toggleShowPassword'>
						<image :src='eye' v-if='isShowPassword' />
						<image :src='eye_close' v-if='!isShowPassword' />
					</view>
				</view>
				<view>
					<button form-type="submit"
						style="background-color:#3B759B;width:90%;color:white;margin-top:10%;font-size:20px;">登录</button>
				</view>
			</form>
		</view>
	</view>
</template>
<script>
	export default {
		data() {
			return {
				isShowPassword: true,
				zhanghao: '',
				mima: '',
				title_login: getApp().globalData.icon + 'login/title_login.png',
				eye: getApp().globalData.icon + 'index/mine/eye.png',
				eye_close: getApp().globalData.icon + 'index/mine/eye_close.png',
			}
		},
		methods: {
			//密码是否显示
			toggleShowPassword: function(e) {
				var isShowPassword = !this.isShowPassword;
				this.isShowPassword = isShowPassword
			},
			//用户密码登录
			formSubmit(e) {
				//获取用户输入信息
				this.zhanghao = e.detail.value.zhanghao; //用户输入账号信息
				this.mima = e.detail.value.mima //用户输入密码信息
				let zhanghao = this.zhanghao
				let mima = this.mima
				//效验账号密码位数
				if (zhanghao.length < 2 || zhanghao.length > 10) {
					uni.showToast({
						title: '账号应在2~10位之间',
						icon: 'none'
					})
					return
				} else if (mima.length < 6 || mima.length > 12) {
					uni.showToast({
						title: '密码应在6~12位之间',
						icon: 'none'
					})
					return
				} else {
					//传入数据到后端,进行登录
					uni.request({
						url: getApp().globalData.position + 'Xcxuser/userlogin',
						header: {
							"Content-Type": "application/x-www-form-urlencoded"
						},
						method: 'POST',
						dataType: 'json',
						data: {
							zhanghao: zhanghao,
							mima: mima
						},
						success: res => { //如果获取到服务器
							// console.log(res.data)
							if (res.data == 1) {
								uni.showToast({
									title: '账号不存在',
									icon: "none",
								})
								return
							} else if (res.data == 2) {
								uni.showToast({
									title: '密码错误',
									icon: "none",
								})
								return
							} else if (res.data == 3) {
								uni.showToast({
									title: '账号已失效',
									icon: "none",
								})
								return
							} else {
								//将账号信息作为全局变量
								getApp().globalData.username = res.data[0].username
								uni.setStorageSync('username', res.data[0].username)
								uni.reLaunch({ //跳转到主页,并携带账号参数
									url: '../../start_production/start_index/start_index?username=' +
										res.data[0].username
								})
								//存入登录变量
							}
						},
						fail: res => {}
					})
				}
			},
		}
	}
</script>

<style>
	page {
		background-color: rgb(242, 242, 242);
		height: 100%;
		width: 100%;
	}

	image {
		height: 80px;
		width: 200px;
		/* border:1px solid black; */
		z-index: 999px;
		position: relative;
		left: 50%;
		margin-left: -100px;
		margin-top: 30%;
		margin-bottom: 10%;

	}

	.eye_position {
		margin: 0px;
		padding: 0px;
		width: 45rpx;
		height: 45rpx;
		padding-right: 2%;
	}

	.eye_position image {
		margin: 0px;
		padding: 0px;
		width: 45rpx;
		height: 45rpx;
	}

	.input-group {
		display: flex;
		align-items: center;
		padding: 25rpx 10rpx;
		margin: 40rpx 3%;
		background: #fff;
		border-radius: 5px;
		border: 2px solid #f4f4f4;
		transition: all .25s ease-in-out;
		width: 88%;
		height: 60rpx;
	}

	.input-group.active {
		border: 2px solid #7acfa6;
	}

	.input-label {
		color: #888;
		font-size: 13pt;
		height: 25rpx;
		line-height: 25rpx;
		padding: 0 25rpx;
		border-right: 1px solid #d8d8d8;
	}

	.input-group input,
	.input-group picker {
		flex: 1;
		font-size: 13pt;
		min-height: 52rpx;
		height: 52rpx;
		line-height: 52rpx;
		padding: 0 25rpx;
	}

	.input-placeholder,
	.input-group picker.placeholder {
		color: #ccc;
	}

	.login-help {
		display: flex;
		margin-left: 71%;
		align-items: center;
		justify-content: flex-end;
		padding: 0 30rpx;
		font-size: 10pt;
		color: #bbb;
	}

	.login-help-img {
		width: 11pt;
		height: 11pt;
		margin: 0 5rpx;
	}

	.confirm-btn {
		font-size: 13pt;
		line-height: 85rpx;
		height: 85rpx;
		background: #1296db;
		color: #fff;
		text-align: center;
		border-radius: 5px;
		margin: 50rpx 3%;
	}

	.confirm-btn:active {
		opacity: .8;
	}
</style>

Second, the label part analysis

<template>
	<view>
		<view class="all">
			<view class="title">
				<image :src="title_login" alt="图片损坏" />
			</view>
			<form class="login-form" @submit="formSubmit">
				<view class="input-group ">
					<text class="input-label">帐号</text>
					<input binf cursor-spacing="30" id="userid" maxlength="18" placeholder="请输入用户名" data-type="Idnumber"
						name='zhanghao' />
				</view>
				<view class="input-group password">
					<text class="input-label">密码</text>
					<input :password='isShowPassword' class="mima" name='mima' cursor-spacing="30" id="passwd"
						placeholder="请输入6位及其以上字符" data-type="password" maxlength="20" />
					<view class="eye_position" @tap='toggleShowPassword'>
						<image :src='eye' v-if='isShowPassword' />
						<image :src='eye_close' v-if='!isShowPassword' />
					</view>
				</view>
				<view>
					<button form-type="submit"
						style="background-color:#3B759B;width:90%;color:white;margin-top:10%;font-size:20px;">登录</button>
				</view>
			</form>
		</view>
	</view>
</template>
  • A tag definition template is used <template>.
  • A page mainly <view>consists of a tab.
  • The page contains a header image and a login form.
  • The header image uses <image>a tag, and :srcthe image path is set by binding properties.
  • The login form uses <form>a tag and calls formSubmita method on submit. Set the name of the account and password in order to obtain it in js, set the form-type="submit" table name in the button, click this button to submit the form
  • The form contains input boxes for account and password. The account input box uses <input>a label, and the password input box uses <input :password='isShowPassword'>a label to v-ifcontrol whether the password is displayed.
  • There is a login button at the end of the form, which triggers the submit event of the form when clicked.

 Three, js

<script>
	export default {
		data() {
			return {
				isShowPassword: true,
				zhanghao: '',
				mima: '',
				title_login: getApp().globalData.icon + 'login/title_login.png',
				eye: getApp().globalData.icon + 'index/mine/eye.png',
				eye_close: getApp().globalData.icon + 'index/mine/eye_close.png',
			}
		},
		methods: {
			//密码是否显示
			toggleShowPassword: function(e) {
				var isShowPassword = !this.isShowPassword;
				this.isShowPassword = isShowPassword
			},
			//用户密码登录
			formSubmit(e) {
				//获取用户输入信息
				this.zhanghao = e.detail.value.zhanghao; //用户输入账号信息
				this.mima = e.detail.value.mima //用户输入密码信息
				let zhanghao = this.zhanghao
				let mima = this.mima
				//效验账号密码位数
				if (zhanghao.length < 2 || zhanghao.length > 10) {
					uni.showToast({
						title: '账号应在2~10位之间',
						icon: 'none'
					})
					return
				} else if (mima.length < 6 || mima.length > 12) {
					uni.showToast({
						title: '密码应在6~12位之间',
						icon: 'none'
					})
					return
				} else {
					//传入数据到后端,进行登录
					uni.request({
						url: getApp().globalData.position + 'Xcxuser/userlogin',
						header: {
							"Content-Type": "application/x-www-form-urlencoded"
						},
						method: 'POST',
						dataType: 'json',
						data: {
							zhanghao: zhanghao,
							mima: mima
						},
						success: res => { //如果获取到服务器
							// console.log(res.data)
							if (res.data == 1) {
								uni.showToast({
									title: '账号不存在',
									icon: "none",
								})
								return
							} else if (res.data == 2) {
								uni.showToast({
									title: '密码错误',
									icon: "none",
								})
								return
							} else if (res.data == 3) {
								uni.showToast({
									title: '账号已失效',
									icon: "none",
								})
								return
							} else {
								//将账号信息作为全局变量
								getApp().globalData.username = res.data[0].username
								uni.setStorageSync('username', res.data[0].username)
								uni.reLaunch({ //跳转到主页,并携带账号参数
									url: '../../start_production/start_index/start_index?username=' +
										res.data[0].username
								})
								//存入登录变量
							}
						},
						fail: res => {}
					})
				}
			},
		}
	}
</script>

1. Data part:

  • isShowPassword: Control whether the password is displayed, the default is true.
  • zhanghao: The value of the account input box, which is empty by default.
  • mima: The value of the password input box, which is empty by default.
  • title_login: The path of the header image of the login page, which is obtained by calling getApp().globalData.iconthe path of the image in the global variable.
  • eye: The path of the eye opening icon, and getApp().globalData.iconthe path of the image in the global variable is also obtained by calling.
  • eye_close: The path of the eye-closing icon, and getApp().globalData.iconthe path of the image in the global variable is also obtained by calling.

2. Method part:

  • toggleShowPassword: The method of switching the display state of the password, which is triggered by clicking the eye icon. In the method isShowPassword, it will be negated to switch between displaying and hiding the password.
  • formSubmit: form submission method, triggered by clicking the login button. The method first obtains the account and password information entered by the user, and then verifies whether the number of digits of the account and password meets the requirements. If the requirements are not met, an appropriate error message will pop up and the method will end. If the requirements are met, a login request is sent to the backend. After the request is successful, judge according to the data returned by the server and make corresponding processing, including popping up error prompts, saving account information to global variables, jumping to the home page, etc.

Backend code (using thinkphp)

//账号密码登录
    public function userlogin()
    {
        //获取用户输入的账号密码
        $zhanghao = input('post.zhanghao');
        $mima = input('post.mima');
        //获取输入账号对应的密码信息
        $user_mima = Db::table('fa_account_info')->where(["username" => $zhanghao])->value('password');
        //获取账号的状态
        $blocked = Db::table('fa_account_info')->where(["username" => $zhanghao])->value('blocked');
        //查找数据库中是否含有此密码(如果账号为空)
        if (empty(Db::table('fa_account_info')->where(["username" => $zhanghao])->select())) {
            return 1;
        }
        //如果账号存在,但密码错误
        else if ($mima != $user_mima) {
            return 2;
        }
        else if($blocked==1){
          return 3;
        }
        //成功登录
        else {
            $login_info = Db::table('fa_account_info')->where(["username" => $zhanghao, "password" => $mima])->select();
            echo json_encode($login_info);
        }
    }

remember account password

Account information stored locally

When entering the correct account password, there is an operation to set the global variable of username, and set username to local cache (see js code)

getApp().globalData.username = res.data[0].username
uni.setStorageSync('username', res.data[0].username)

Enter the system execution method (App.vue)

full code

<script>
	export default {
		onLaunch: function() {
			// 展示本地存储能力
			const logs = uni.getStorageSync('logs') || []
			logs.unshift(Date.now())
			uni.setStorageSync('logs', logs)
			// 登录
			const username = uni.getStorageSync('username')
			console.log('全局'+username)
			this.globalData.username=username
			if(username){
			  uni.reLaunch({
				  url:'./pages/start_production/start_index/start_index?username='+username,
			  })
			}
		},
		onShow: function() {
			// console.log('App Show')
		},
		onHide: function() {
			// console.log('App Hide')
		},
		globalData:{
			position:'XXX',
			icon:'XXX',
			username:''
		}
	}
</script>

<style>

</style>

onLaunchIs a commonly used life cycle function, which is triggered when the App starts and can be used to perform some initialization operations and logic.

 So here you only need to onLaunch judge whether the local cache exists in , if there is a direct login, if it does not exist, log in with the account and password

  •  First, get the local storage data named 'logs' through uni.getStorageSyncthe method, and return an empty array if the data does not exist. uni.getStorageSyncIt is an interface provided by uni-app, which is used to obtain data from local storage.
  • Then, add the current timestamp (Date.now()) to the beginning of the obtained logs array to record the time when the application was started. unshiftmethod is used to insert elements at the beginning of the array.

  • Next, use uni.setStorageSyncthe method to restore the updated logs array to local storage. uni.setStorageSyncUsed to store data into local storage.

  • Execution continues by uni.getStorageSyncgetting the local storage data named 'username' and assigning it to const usernamethe variable. This assumes that 'username' is a previously saved user login.

  • Use to console.logprint out global usernamevariables.

  • Next, this.globalData.usernamesave usernamethe value of to a global variable for use in other pages of the app via . Among them, thisrepresents the current applet instance, globalDatawhich is a custom attribute used to store globally shared data.

  • Carry out conditional judgment, if usernameexists (that is, the user is logged in), use uni.reLaunchthe method to jump to ./pages/start_production/start_index/start_indexthe page, and usernamepass it as a parameter to the target page.

Guess you like

Origin blog.csdn.net/weixin_46001736/article/details/131920632