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