uni-app:实现账号密码登录,并且实现当页面登录过该账号在下次登录时无需再输入账号密码(本地缓存实现)

news2024/10/10 18:29:34

效果

前端代码

一、完整代码

<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>

二、标签部分解析

<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>
  • 使用了<template>标签定义模板。
  • 页面主要由一个<view>标签组成。
  • 页面包含一个标题图片和一个登录表单。
  • 标题图片使用了<image>标签,通过:src绑定属性来设置图片路径。
  • 登录表单使用了<form>标签,并在提交时调用formSubmit方法。对账号和密码进行name的设置为了在js中获取,button中设置form-type="submit"表名点击此按钮进行表单提交
  • 表单包含了账号和密码的输入框,账号输入框使用了<input>标签,密码输入框使用了<input :password='isShowPassword'>标签,通过v-if控制密码是否显示。
  • 表单最后有一个登录按钮,点击时触发表单的提交事件。

 三、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、数据部分:

  • isShowPassword:控制密码是否显示的状态,默认为true
  • zhanghao:账号输入框的值,默认为空。
  • mima:密码输入框的值,默认为空。
  • title_login:登录页面标题图片的路径,通过调用getApp().globalData.icon获取全局变量中的图片路径。
  • eye:眼睛打开图标的路径,同样通过调用getApp().globalData.icon获取全局变量中的图片路径。
  • eye_close:眼睛关闭图标的路径,同样通过调用getApp().globalData.icon获取全局变量中的图片路径。

2、方法部分:

  • toggleShowPassword:切换密码显示状态的方法,通过点击眼睛图标触发。方法中将isShowPassword取反,实现密码显示与隐藏的切换。
  • formSubmit:表单提交方法,通过点击登录按钮触发。方法首先获取用户输入的账号和密码信息,然后验证账号和密码的位数是否符合要求。如果不符合要求,将弹出相应的错误提示,并结束方法。如果符合要求,则向后端发送登录请求。请求成功后,根据服务器返回的数据进行判断并做出相应的处理,包括弹出错误提示、保存账号信息到全局变量、跳转到主页等。

后端代码(采用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);
        }
    }

记住账户密码

账号信息存入本地

在输入正确的账号密码时,有操作设置username的全局变量,以及设置username为本地缓存(见js代码)

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

进入系统执行方法(App.vue)

完整代码

<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>

onLaunch 是一个常用的生命周期函数,它在 App 启动时被触发,可以用来执行一些初始化操作和逻辑。

 所以这里只需要在onLaunch 中判断本地缓存是否存在即可,如果存在直接登录,不存在便进行账号密码登录

  •  首先,通过 uni.getStorageSync 方法获取名为 'logs' 的本地存储数据,如果该数据不存在则返回一个空数组。uni.getStorageSync 是 uni-app 提供的接口,用于从本地存储中获取数据。
  • 然后,将当前时间戳(Date.now())添加到获取到的 logs 数组的开头,以记录本次应用启动的时间。unshift 方法用于在数组开头插入元素。

  • 接着,使用 uni.setStorageSync 方法将更新后的 logs 数组重新存储到本地存储中。uni.setStorageSync 用于将数据存储到本地存储中。

  • 继续执行,通过 uni.getStorageSync 获取名为 'username' 的本地存储数据,将其赋值给 const username 变量。这里假设 'username' 是之前保存的用户登录信息。

  • 使用 console.log 打印出全局的 username 变量。

  • 接下来,通过 this.globalData.usernameusername 的值保存到全局变量中,以便在应用的其他页面中使用。其中,this 表示当前小程序实例,globalData 是一个自定义属性,用来存储全局共享的数据。

  • 进行条件判断,如果 username 存在(即用户已登录),则使用 uni.reLaunch 方法跳转到 ./pages/start_production/start_index/start_index 页面,并将 username 作为参数传递给目标页面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/790179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA面试总结-Redis篇章(二)——缓存击穿

JAVA面试总结-Redis篇章&#xff08;二&#xff09; 缓存击穿解决方案一&#xff1a;互斥锁解决方案二&#xff1a;逻辑过期![在这里插入图片描述](https://img-blog.csdnimg.cn/176dfab3e26044a9a730fabea4314e8e.png) 缓存击穿 解决方案一&#xff1a;互斥锁 解决方案二&…

SpringBoot-5

Spring Boot 的项目属性配置 在项目中很多时候需要用到一些配置的信息&#xff0c;这些信息可能在测试环境和生产环境下会有不同的配置&#xff0c;后面根据实际业务情况有可能还会做修改&#xff0c;针对这种情况不能将这些配置在代码中写死&#xff0c;最好就是写到配置文件…

Rust vs Go:常用语法对比(六)

题图来自[1] 101. Load from HTTP GET request into a string Make an HTTP request with method GET to URL u, then store the body of the response in string s. 发起http请求 package mainimport ( "fmt" "io/ioutil" "net" "net/http…

Fiddler使用说明及中文绿化版

Fiddler是最常用的Web调试工具之一。 对于开发来说&#xff0c;前端可以通过fiddler代理来调试JS、CSS、HTML样式。后端可以通过fiddler查看请求和相应&#xff0c;定位问题。 对于测试来说&#xff0c;可以通过抓包方式修改前端请求参数和模拟后端返回&#xff0c;快速定位缺…

Pr LOGO平滑过渡效果

哈喽&#xff0c;各位小伙伴&#xff01;今天我们来学习一下如何制作LOGO平滑过渡效果&#xff1f; 准备工作 两个透明LOGO&#xff0c;一个水滴音效 ​新建序列 新建一个1920*1080的序列&#xff0c;将图片拖拽至轨道 CtrlR 图片时长设置为3SCtrlD 快速添加过渡效果右键…

【Python】生成md5码

目录 1 代码 2 运行结果 使用hashlib库来生成md5码。如下代码会生成Happy every day的md5哈希值。 1 代码 import hashlibdef generate_md5(string):md5 hashlib.md5()md5.update(string.encode(utf-8))return md5.hexdigest()if __name__ __main__:MD5 generate_md5(&qu…

测试开源C#人脸识别模块ViewFaceCore(3:人脸特征提取和对比)

ViewFaceCore模块的FaceRecognizer支持人脸特征提取和对比&#xff0c;将人脸中的关键信息转换为矢量信息&#xff0c;然后通过计算两个矢量的相似度以判断人脸的相似程序。   调用FaceRecognizer对比人脸相似度主要包括以下步骤&#xff1a;   1&#xff09;调用faceDetec…

第一百一十六天学习记录:C++提高:STL-string(黑马教学视频)

string基本概念 string是C风格的字符串&#xff0c;而string本质上是一个类 string和char区别 1、char是一个指针 2、string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char型的容器。 特点&#xff1a; string类内部封装了很多成员方…

idea社区版(2023.1)设置spring boot项目热启动

热启动 在开发过程中&#xff0c;当写完一个功能我们需要运行应用程序测试时需要重启服务器&#xff0c;一个最简单的项目也要花费10多秒&#xff0c;如果是更大的项目则耗时更多。SpringBoot提供了spring-boot-devtools&#xff0c;使得项目在发生改动时能够自动重启应用 id…

hadoop3编译安装

1.参考资料 官方的https://github.com/apache/hadoop/blob/trunk/BUILDING.txt 2.编译环境 Linux系统&#xff1a;Centos7.2 Jdk版本&#xff1a;jdk1.8 cmake版本&#xff1a;3.19 Hadoop版本&#xff1a;3.1.2 Maven版本&#xff1a;3.6.3 Protobuf版本&#xff1a;2…

【数据分析专栏之Python篇】二、Jupyer Notebook安装配置及基本使用

文章目录 前言一、Jupter Notebook是什么1.1 简介1.2 组成部分1.3 Jupyter Notebook的主要特点 二、为什么使用Jupyter Notebook?三、安装四、Jupyter Notebok配置4.1 基本配置4.2 配置开机自启与后台运行4.3 开启代码自动补全 五、两种键盘输入模式5.1 编辑模式5.2 命令模式5…

J2EE通用分页02

目录 一.重构-提取公用方法 1.为了进行公共方法的抽取&#xff0c;需要找出上面实习中的可通用部分&#xff0c;和差异化部分 2.公用方法封装思路 3. 具体实现 二.分页标签 2.1 准备一个Servlet 3.2 结果展示页面 三. 过滤器解决中文乱码问题 四.加入分页功能 四…

Qt Core学习日记——第七天QMetaObject(上)

每一个声明Q_OBJECT的类都具有QMetaObject对象 Q_OBJECT宏源代码&#xff1a; #define Q_OBJECT \ public: \ QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ virtual const QMetaObject *metaObject() const; \ vir…

Rust vs Go:常用语法对比(五)

题图来自 Rust vs Go 2023[1] 81. Round floating point number to integer Declare integer y and initialize it with the rounded value of floating point number x . Ties (when the fractional part of x is exactly .5) must be rounded up (to positive infinity). 按规…

垃圾回收标记阶段算法

1.标记阶段的目的 主要是在GC在前&#xff0c;判断出哪些是有用的对象&#xff0c;哪些是需要回收的对象&#xff0c;只有被标记为垃圾对象&#xff0c;GC才会对其进行垃圾回收。判断对象是否为垃圾对象的两种方式&#xff1a;引用计数算法和可达性分析算法。 2.引用计数算法…

MySQL基础(一)

目录 前言 一、概述 1.什么是数据库 2.数据库能干什么 3.为什么要用数据库&#xff0c;优势、特性 二、数据库类型 &#xff08;一&#xff09;、关系型数据库&#xff0c;RDBMS 1.概述 2.特点 3.代表产品 &#xff08;二&#xff09;、非关系型数据库&#xff0c;No…

性能测试常见故障和解决思路

目录 一、性能问题分析流程 二、内存溢出 &#xff08;一&#xff09;堆内存溢出 &#xff08;二&#xff09;永久代/方法区溢出 &#xff08;三&#xff09;栈内存溢出 &#xff08;四&#xff09;系统内存溢出 三、CPU过高 &#xff08;一&#xff09;us cpu过高 &a…

flink cdc环境搭建

1.下载flink https://archive.apache.org/dist/flink/flink-1.12.2/ 2.修改flink-conf.yaml #根据自己电脑核数修改&#xff0c;这里我设置为4&#xff0c;因为系统分配了4核 jobmanager.rpc.address: localhost #主机名根据自己设定 taskmanager.numberOfTaskSlots: 4 3.下载…

Databend 开源周报第 103 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 创建网络策略 …

机器学习深度学习——图像分类数据集

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——softmax回归&#xff08;下&#xff09; &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习…