21 登录页面(短信验证倒计时,第三方登录样式渲染,状态栏防遮挡组件)
一 简单实现登录页面
效果图:
要点:
1 input虽然是内联元素,但是宽高 margin padding 全都有效。除了不换行和正常的块状元素区别不大
2 扩大点击范围可以考虑使用padding
3 可以考虑直接使用uni-status-bar/uni-status-bar.vue 组件来解决遮盖状态栏的问题。
<template>
<view>
<uni-status-bar></uni-status-bar>
<view class="iconfont font-weight-bold icon-guanbi flex align-center justify-center font-lg"
style="width: 100rpx; height: 100rpx;"
hover-class="text-muted"></view>
<!-- 账号密码登录 -->
<template v-if="status">
<view class="font-lgger flex align-center justify-center" style="margin-top:100rpx;">
账号密码登录
</view>
<view class="px-2">
<input class=" border-bottom font-md p-3" type="text"
style="margin-top:100rpx"
value="" placeholder="昵称/手机号/邮箱" />
<!-- align-stretch直接保证了各个元素高度的统一,就不只是剧中对齐了 -->
<view class="flex align-stretch border-bottom ">
<input class="flex-1 font-md p-3" type="text"
value="" placeholder="请输入密码" />
<view class="text-muted flex align-center justify-center" style="width: 160rpx;">
忘记密码
</view>
</view>
</view>
</template>
<template v-else>
<view class="font-lgger flex align-center justify-center" style="margin-top:100rpx;">
短信验证码登录
</view>
<view class="px-2">
<view class="flex align-center border-bottom" style="margin-top:100rpx">
<view class="flex align-center justify-center font-weight-bold font-md">
+86
</view>
<input class="font-md p-3" type="text"
value="" placeholder="手机号" />
<!-- <view class="flex align-center justify-center font-weight-bold bg-main">
+86
</view> -->
</view>
<!-- align-stretch直接保证了各个元素高度的统一,就不只是剧中对齐了 -->
<view class="flex align-center border-bottom ">
<input class="flex-1 font-md p-3" type="text"
value="" placeholder="请输入验证码" />
<view class="text-white rounded flex font-md p-1 align-center justify-center bg-main " style="width: 180rpx;">
获取验证码
</view>
</view>
</view>
</template>
<view class="px-3 " style="padding-top:60rpx">
<button class="bg-main text-white" style="border-radius: 50rpx;border: 0;" type="primary">登录</button>
</view>
<view class="flex align-center justify-center mx-2 my-2">
<view class="text-primary font py-2 mx-2 " @click="changeStatus">{{status?'短信验证登录':'账号密码登录'}}</view>
<text>|</text>
<view class="text-primary font py-2 mx-2">登录遇到问题</view>
</view>
<view class="flex align-center justify-center py-2">
<view class="" style="height: 1rpx;background-color: #CCCCCC;width: 100rpx;"></view>
<view class="text-muted font">
社交账号登录
</view>
<view class="" style="height: 1rpx;background-color: #CCCCCC;width: 100rpx;"></view>
</view>
<view class="flex align-center justify-between" style="padding:20rpx 100rpx">
<view class="iconfont icon-QQ bg-primary text-white font-lgger rounded-circle flex align-center justify-center" style="height:100rpx;width:100rpx;">
</view>
<view class="iconfont icon-QQ bg-primary text-white font-lgger rounded-circle flex align-center justify-center" style="height:100rpx;width:100rpx;">
</view>
<view class="iconfont icon-QQ bg-primary text-white font-lgger rounded-circle flex align-center justify-center" style="height:100rpx;width:100rpx;">
</view>
</view>
<view class="flex align-center justify-center mt-2">
<text class="text-muted font">注册即代表您同意</text>
<text class="font text-primary">《xxx社区协议》</text>
</view>
</view>
</template>
<script>
import uniStatusBar from '@/components/uni-ui/uni-status-bar/uni-status-bar.vue'
export default {
components:{
uniStatusBar
},
data() {
return {
status:true
}
},
methods: {
changeStatus(){
this.status = !this.status
}
}
}
</script>
<style>
</style>
二 相对完善实现登录页面
效果图:
要点:
1 完善了输入框没填满内容,输入框暗色无法点击。
2 完善了发送验证码倒计时渲染。
3 完善并且封装了部分第三方登录的渲染样式。
代码:
<template>
<view>
<!-- 状态栏占位 -->
<uni-status-bar></uni-status-bar>
<!-- 左上角的叉 -->
<view class="iconfont font-weight-bold icon-guanbi flex align-center justify-center font-lg"
style="width: 100rpx; height: 100rpx;"
hover-class="text-muted"
@click="back"></view>
<!-- 账号密码登录 -->
<template v-if="status">
<view class="font-lgger flex align-center justify-center" style="margin-top:100rpx;">
账号密码登录
</view>
<view class="px-2">
<input class=" border-bottom font-md p-3" type="text"
style="margin-top:100rpx"
value="" placeholder="昵称/手机号/邮箱"
v-model="username"/>
<!-- align-stretch直接保证了各个元素高度的统一,就不只是剧中对齐了 -->
<view class="flex align-stretch border-bottom ">
<input class="flex-1 font-md p-3" type="text"
value="" placeholder="请输入密码"
v-model="password"/>
<view class="text-muted flex align-center justify-center" style="width: 160rpx;">
忘记密码
</view>
</view>
</view>
</template>
<!-- 短信验证登录 -->
<template v-else>
<view class="font-lgger flex align-center justify-center" style="margin-top:100rpx;">
短信验证码登录
</view>
<view class="px-2">
<!-- 手机号 -->
<view class="flex align-center border-bottom" style="margin-top:100rpx">
<view class="flex align-center justify-center font-weight-bold font-md">
+86
</view>
<input class="font-md p-3" type="text"
value="" placeholder="手机号"
v-model="phone"/>
<!-- <view class="flex align-center justify-center font-weight-bold bg-main">
+86
</view> -->
</view>
<!-- 验证码 -->
<!-- align-stretch直接保证了各个元素高度的统一,就不只是剧中对齐了 -->
<view class="flex align-center border-bottom ">
<input class="flex-1 font-md p-3" type="text"
value="" placeholder="请输入验证码"
v-model="code"/>
<view class="text-white rounded flex font-md p-1 align-center justify-center bg-main " style="width: 180rpx;"
@click="getCode"
:class="codeTime>0 ?'bg-main-disabled':'bg-main'">
{{codeTime>0 ? codeTime: '获取验证码'}}
</view>
</view>
</view>
</template>
<!-- 登录按钮 -->
<view class="px-3 " style="padding-top:60rpx">
<button class=" text-white" style="border-radius: 50rpx;border: 0;" type="primary"
:disabled="disabled"
:class="disabled?'bg-main-disabled':'bg-main'"
@click="submit">登录</button>
</view>
<view class="flex align-center justify-center mx-2 my-2">
<view class="text-primary font py-2 mx-2 " @click="changeStatus">{{status?'短信验证登录':'账号密码登录'}}</view>
<text>|</text>
<view class="text-primary font py-2 mx-2">登录遇到问题</view>
</view>
<view class="flex align-center justify-center py-2">
<view class="" style="height: 1rpx;background-color: #CCCCCC;width: 100rpx;"></view>
<view class="text-muted font">
社交账号登录
</view>
<view class="" style="height: 1rpx;background-color: #CCCCCC;width: 100rpx;"></view>
</view>
<!-- 其他登录方式 -->
<other-login></other-login>
<view class="flex align-center justify-center mt-2">
<text class="text-muted font">注册即代表您同意</text>
<text class="font text-primary">《xxx社区协议》</text>
</view>
<!-- <view class="">
</view> -->
</view>
</template>
<script>
import uniStatusBar from '@/components/uni-ui/uni-status-bar/uni-status-bar.vue'
import otherLogin from '@/components/common/outer-login.vue'
export default {
components:{
uniStatusBar,
otherLogin
},
data() {
return {
status:true,
username:"",
password:"",
phone:"",
code:"",
codeTime:0
}
},
computed:{
disabled(){
if((this.username===''||this.password==='')&&(this.phone===''||this.code==='')){
return true
}
return false
}
},
methods: {
// 后退1页
back(){
uni.navigateBack({
delta:1
})
},
// 初始化表单
initForm(){
this.username = ''
this.password = ''
this.phone = ''
this.code = ''
},
// 切换账号密码登录or短信登录
changeStatus(){
this.status = !this.status
},
// 获取验证码
getCode(){
// 防止重复获取
if (this.codeTime>0){
return;
}
// 倒计时
this.codeTime = 5
// 箭头函数可以直接拿到外面的this的内容
let timer = setInterval(()=>{
if (this.codeTime >= 1){
this.codeTime--
} else{
clearInterval(timer)
}
},1000)
},
// 表单验证
validate(){
//手机号正则 只是针对验证码的手机号字段,其他并未做兼容。
var mPattern = /^1[34578]\d{9}$/;
if (!mPattern.test(this.phone)) {
uni.showToast({
title: '手机号格式不正确',
icon: 'none'
});
return false
}
// ...更多验证
return true
},
// 提交
submit(){
// 表单验证
if (!this.validate()) return;
// 提交后端
// 登录成功处理
}
}
}
</script>
<style>
</style>
Components/common/outer-login.vue
<template>
<view>
<view class="flex align-center justify-between" style="padding:20rpx 100rpx">
<view
v-for="(item,index) in providerList" :key="index"
class="iconfont text-white font-lgger rounded-circle flex align-center justify-center"
style="height:100rpx;width:100rpx;"
:class="item.icon+' '+item.bgColor">
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
providerList:[]
}
},
mounted() {
uni.getProvider({
service: 'oauth',
success: (result) => {
console.log(result.provider)
this.providerList = result.provider.map((value) => {
// 注释
// [weixin,qq,sinaweibo] 通过map函数变成
// [{
// providerName = '微信登录'
// icon : 'icon-weixin'
// bgColor :'bg-success'
// },
// {},{}.....]
let providerName = '';
let icon = ''
let bgColor = ''
switch (value) {
case 'weixin':
providerName = '微信登录'
// 自己在这个位置添加上需要渲染的信息 如 icon bgColor
icon = 'icon-weixin'
bgColor = 'bg-success'
break;
case 'qq':
providerName = 'QQ登录'
icon = 'icon-QQ'
bgColor = 'bg-primary'
break;
case 'sinaweibo':
providerName = '新浪微博登录'
icon = 'icon-xinlangweibo'
bgColor = 'bg-warning'
break;
}
// 返回的时候
return {
name: providerName,
id: value,
icon:icon,
bgColor:bgColor
}
});
},
fail: (error) => {
console.log('获取登录通道失败', error);
}
});
},
methods: {
}
}
</script>
<style>
</style>