效果
前端代码
一、完整代码
<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.zhanghaolet 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].usernameuni.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.zhanghaolet 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].usernameuni.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=usernameif(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.username
将username
的值保存到全局变量中,以便在应用的其他页面中使用。其中,this
表示当前小程序实例,globalData
是一个自定义属性,用来存储全局共享的数据。进行条件判断,如果
username
存在(即用户已登录),则使用uni.reLaunch
方法跳转到./pages/start_production/start_index/start_index
页面,并将username
作为参数传递给目标页面。