Browse Source

登陆和注册页面优化

master
xsx 6 months ago
parent
commit
3456e9ba08
  1. 282
      im-uniapp/pages/login/login.vue
  2. 341
      im-uniapp/pages/register/register.vue

282
im-uniapp/pages/login/login.vue

@ -1,58 +1,93 @@
<template>
<view class="login">
<!-- 主要内容区域 -->
<view class="content">
<!-- Logo和标题区域 -->
<view class="header">
<view class="title">欢迎登录</view>
<view class="subtitle">登录您的账号开启聊天之旅</view>
</view>
<!-- 表单区域 -->
<view class="form-container">
<view class="form">
<uni-forms :modelValue="loginForm" :rules="rules" validate-trigger="bind">
<uni-forms-item name="userName">
<uni-easyinput type="text" v-model="loginForm.userName" prefix-icon="person" placeholder="用户名" />
</uni-forms-item>
<uni-forms-item name="password">
<uni-easyinput type="password" v-model="loginForm.password" prefix-icon="locked" placeholder="密码" />
</uni-forms-item>
<button class="btn-submit" @click="submit" type="primary">登录</button>
</uni-forms>
<view class="form-item" :class="{'focused': userNameFocused}">
<view class="icon-wrapper">
<view class="icon iconfont icon-username"></view>
</view>
<input class="input" type="text" v-model="dataForm.userName" placeholder="用户名"
@focus="userNameFocused = true" @blur="userNameFocused = false" />
</view>
<view class="form-item" :class="{'focused': passwordFocused}">
<view class="icon-wrapper">
<view class="icon iconfont icon-pwd"></view>
</view>
<input class="input" :type="isShowPwd?'text':'password'" v-model="dataForm.password"
placeholder="密码" @focus="passwordFocused = true" @blur="passwordFocused = false" />
<view class="icon-suffix iconfont" :class="isShowPwd?'icon-pwd-show':'icon-pwd-hide'"
@click="onSwitchShowPwd"></view>
</view>
<navigator class="nav-register" url="/pages/register/register">
没有账号,前往注册
</view>
<!-- 登录按钮 -->
<button class="submit-btn" @click="submit" type="primary">
<view class="btn-content">
<text class="btn-text">立即登录</text>
</view>
</button>
<!-- 底部导航 -->
<view class="nav-tool-bar">
<view class="nav-register">
<navigator url="/pages/register/register" class="register-link">
<text class="register-text">没有账号</text>
<text class="register-highlight">立即注册</text>
</navigator>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import UNI_APP from '@/.env.js';
export default {
data() {
return {
loginForm: {
isShowPwd: false,
userNameFocused: false,
passwordFocused: false,
dataForm: {
terminal: 1, // APP
userName: '',
password: ''
},
rules: {
userName: {
rules: [{
required: true,
errorMessage: '请输入用户名',
}]
},
password: {
rules: [{
required: true,
errorMessage: '请输入密码',
}]
}
}
}
},
methods: {
submit() {
if (!this.dataForm.userName) {
return uni.showToast({
title: "请输入您的账号",
icon: "none"
})
}
if (!this.dataForm.password) {
return uni.showToast({
title: "请输入您的密码",
icon: "none"
})
}
this.$http({
url: '/login',
data: this.loginForm,
data: this.dataForm,
method: 'POST'
}).then(loginInfo => {
console.log("登录成功,自动跳转到聊天页面...")
uni.setStorageSync("userName", this.loginForm.userName);
uni.setStorageSync("password", this.loginForm.password);
uni.setStorageSync("userName", this.dataForm.userName);
uni.setStorageSync("password", this.dataForm.password);
uni.setStorageSync("isAgree", this.isAgree);
uni.setStorageSync("loginInfo", loginInfo);
// App.vue
getApp().$vm.init()
@ -60,44 +95,199 @@ export default {
uni.switchTab({
url: "/pages/chat/chat"
})
}).catch((e) => {
console.log("登录失败:", e);
})
}
//
getApp().$vm.unloadStore();
},
onSwitchShowPwd() {
this.isShowPwd = !this.isShowPwd;
},
},
onLoad() {
this.loginForm.userName = uni.getStorageSync("userName");
this.loginForm.password = uni.getStorageSync("password");
this.dataForm.userName = uni.getStorageSync("userName");
this.dataForm.password = uni.getStorageSync("password");
}
}
</script>
<style lang="scss" scoped>
.login {
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
//
.content {
position: relative;
display: flex;
flex-direction: column;
margin-top: 120rpx;
// #ifdef APP-PLUS
margin-top: calc(120rpx + var(--status-bar-height));
// #endif
padding: 0 60rpx;
}
//
.header {
text-align: center;
padding: 80rpx 0;
.title {
padding-top: 250rpx;
padding-bottom: 50rpx;
color: $im-color-primary;
text-align: center;
font-size: 24px;
font-weight: bold;
font-size: 48rpx;
font-weight: 700;
margin-bottom: 20rpx;
letter-spacing: 2rpx;
}
.subtitle {
color: $im-text-color-light;
font-size: 28rpx;
opacity: 0.8;
}
}
//
.form-container {
display: flex;
flex-direction: column;
}
//
.form {
padding: 50rpx;
margin-bottom: 20rpx;
.form-item {
position: relative;
display: flex;
align-items: center;
padding: 0 30rpx;
height: 100rpx;
margin: 24rpx 0;
border-radius: 25rpx;
background: rgba(255, 255, 255, 0.9);
border: 2rpx solid transparent;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
.btn-submit {
margin-top: 80rpx;
&.focused {
border-color: $im-color-primary;
box-shadow: 0 8rpx 32rpx rgba($im-color-primary, 0.15);
transform: translateY(-2rpx);
}
.icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
margin-right: 30rpx;
border-radius: 50%;
background: $im-bg-active;
transition: all 0.3s ease;
.icon {
font-size: 32rpx;
color: $im-color-primary;
font-weight: bold;
}
}
&.focused .icon-wrapper {
transform: scale(1.1);
}
.input {
flex: 1;
font-size: 32rpx;
color: #333;
background: transparent;
border: none;
outline: none;
&::placeholder {
color: $im-text-color-light;
font-size: 30rpx;
}
}
.icon-suffix {
font-size: 36rpx;
padding: 10rpx;
}
}
}
//
.submit-btn {
height: 100rpx;
border-radius: 50rpx;
border: none;
box-shadow: 0 8rpx 32rpx rgba($im-color-primary, 0.3);
transition: all 0.3s ease;
overflow: hidden;
position: relative;
width: 100%;
&:active {
transform: translateY(2rpx);
box-shadow: 0 4rpx 16rpx rgba($im-color-primary, 0.4);
&::before {
left: 100%;
}
}
.btn-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: white;
font-size: $im-font-size-large;
font-weight: 600;
.btn-text {
margin-right: 10rpx;
}
}
&:active .btn-icon {
transform: translateX(4rpx);
}
}
//
.nav-tool-bar {
padding: 40rpx 0 60rpx;
display: flex;
align-items: center;
justify-content: space-between;
.nav-register {
position: fixed;
width: 100%;
bottom: 100rpx;
.register-link {
display: flex;
align-items: center;
text-decoration: none;
.register-text {
color: $im-text-color-light;
font-size: $im-font-size-small;
margin-right: 8rpx;
}
.register-highlight {
color: $im-color-primary;
text-align: center;
font-size: $im-font-size;
font-size: $im-font-size-small;
font-weight: 600;
}
}
}
}
}
</style>

341
im-uniapp/pages/register/register.vue

@ -1,89 +1,143 @@
<template>
<view class="register">
<view class="title">欢迎注册</view>
<!-- 主要内容区域 -->
<view class="content">
<!-- Logo和标题区域 -->
<view class="header" @longpress.prevent="onLongPressHeader()">
<view class="title"> 用户注册 </view>
<view class="subtitle">创建您的账号开始精彩旅程</view>
</view>
<!-- 表单区域 -->
<view class="form-container">
<view class="form">
<uni-forms ref="form" :modelValue="dataForm" :rules="rules" validate-trigger="bind" label-width="80px">
<uni-forms-item name="userName" label="用户名">
<uni-easyinput type="text" v-model="dataForm.userName" placeholder="用户名" maxlength="20"/>
</uni-forms-item>
<uni-forms-item name="nickName" label="昵称">
<uni-easyinput type="text" v-model="dataForm.nickName" placeholder="昵称" maxlength="20"/>
</uni-forms-item>
<uni-forms-item name="password" label="密码">
<uni-easyinput type="password" v-model="dataForm.password" placeholder="密码" maxlength="20"/>
</uni-forms-item>
<uni-forms-item name="corfirmPassword" label="确认密码">
<uni-easyinput type="password" v-model="dataForm.corfirmPassword" placeholder="确认密码" maxlength="20"/>
</uni-forms-item>
<button class="btn-submit" @click="submit" type="primary">注册并登录</button>
</uni-forms>
</view>
<navigator class="nav-login" url="/pages/login/login">
返回登录页面
<!-- 用户名输入 -->
<view class="form-item" :class="{'focused': userNameFocused}">
<view class="icon-wrapper">
<view class="icon iconfont icon-username"></view>
</view>
<input class="input" type="text" v-model="dataForm.userName" placeholder="请填写用户名"
@focus="userNameFocused = true" @blur="userNameFocused = false" />
</view>
<!-- 用户名输入 -->
<view class="form-item" :class="{'focused': nickNameFocused}">
<view class="icon-wrapper">
<view class="icon iconfont icon-username"></view>
</view>
<input class="input" type="text" v-model="dataForm.nickName" placeholder="请填写昵称"
@focus="nickNameFocused = true" @blur="nickNameFocused = false" />
</view>
<!-- 密码输入 -->
<view class="form-item" :class="{'focused': passwordFocused}">
<view class="icon-wrapper">
<view class="icon iconfont icon-pwd"></view>
</view>
<input class="input" :type="isShowPwd?'text':'password'" v-model="dataForm.password"
placeholder="请设置密码" @focus="passwordFocused = true" @blur="passwordFocused = false" />
<view class="icon-suffix iconfont" :class="isShowPwd?'icon-pwd-show':'icon-pwd-hide'"
@click="onSwitchShowPwd"></view>
</view>
<!-- 确认密码输入 -->
<view class="form-item" :class="{'focused': confirmPasswordFocused}">
<view class="icon-wrapper">
<view class="icon iconfont icon-pwd"></view>
</view>
<input class="input" :type="isShowConfirmPwd?'text':'password'"
v-model="dataForm.confirmPassword" placeholder="确认密码" @focus="confirmPasswordFocused = true"
@blur="confirmPasswordFocused = false" />
<view class="icon-suffix iconfont" :class="isShowConfirmPwd?'icon-pwd-show':'icon-pwd-hide'"
@click="onSwitchShowConfirmPwd"></view>
</view>
<!-- 注册按钮 -->
<button class="submit-btn" @click="submit" type="primary">
<view class="btn-content">
<text class="btn-text">注册并登录</text>
</view>
</button>
<!-- 底部导航 -->
<view class="nav-tool-bar">
<view class="nav-login">
<navigator url="/pages/login/login" class="login-link">
<text class="login-text">已有账号</text>
<text class="login-highlight">立即登录</text>
</navigator>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import UNI_APP from '@/.env.js';
export default {
data() {
return {
isShowPwd: false,
isShowConfirmPwd: false,
userNameFocused: false,
nickNameFocused: false,
passwordFocused: false,
confirmPasswordFocused: false,
dataForm: {
userName: '',
nickName: '',
password: '',
corfirmPassword: ''
},
rules: {
userName: {
rules: [{
required: true,
errorMessage: '请输入用户名',
}]
confirmPassword: ''
}
}
},
nickName: {
rules: [{
required: true,
errorMessage: '请输入昵称',
}]
methods: {
onSwitchShowPwd() {
this.isShowPwd = !this.isShowPwd;
},
password: {
rules: [{
required: true,
errorMessage: '请输入密码',
}]
onSwitchShowConfirmPwd() {
this.isShowConfirmPwd = !this.isShowConfirmPwd;
},
corfirmPassword: {
rules: [{
required: true,
errorMessage: '请输入确认密码',
}, {
validateFunction: (rule, value, data, callback) => {
if (data.password != value) {
callback('两次密码输入不一致')
}
return true;
submit() {
if (!this.dataForm.userName) {
return uni.showToast({
title: '请输入用户名',
icon: 'none'
});
}
}]
if (!this.dataForm.password) {
return uni.showToast({
title: '请输入密码',
icon: 'none'
});
}
if (!this.dataForm.confirmPassword) {
return uni.showToast({
title: '请输入确认密码',
icon: 'none'
});
}
if (this.dataForm.confirmPassword != this.dataForm.password) {
return uni.showToast({
title: '两次密码输入不一致',
icon: 'none'
});
}
},
methods: {
submit() {
this.$refs.form.validate().then(() => {
this.$http({
url: '/register',
data: this.dataForm,
method: 'POST'
}).then(() => {
let appName = uni.getSystemInfoSync().appName
uni.showToast({
title: "注册成功,您已成为盒子IM的用户",
title: `注册成功,您已成为${appName}的用户`,
icon: 'none'
})
this.login();
})
})
},
login() {
const loginForm = {
@ -107,6 +161,8 @@ export default {
url: "/pages/chat/chat"
})
})
//
getApp().$vm.unloadStore();
}
}
}
@ -114,31 +170,182 @@ export default {
<style lang="scss" scoped>
.register {
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
//
.content {
flex: 1;
position: relative;
display: flex;
flex-direction: column;
margin-top: 120rpx;
// #ifdef APP-PLUS
margin-top: calc(120rpx + var(--status-bar-height));
// #endif
padding: 0 60rpx;
}
//
.header {
text-align: center;
padding: 80rpx 0;
.title {
padding-top: 250rpx;
padding-bottom: 50rpx;
color: $im-color-primary;
text-align: center;
font-size: 24px;
font-weight: 600;
font-size: 48rpx;
font-weight: 700;
margin-bottom: 20rpx;
letter-spacing: 2rpx;
}
.subtitle {
color: $im-text-color-light;
font-size: 28rpx;
opacity: 0.8;
}
}
//
.form-container {
display: flex;
flex-direction: column;
}
//
.form {
padding: 50rpx;
height: 830rpx;
display: flex;
flex-direction: column;
justify-content: center;
.form-item {
position: relative;
display: flex;
align-items: center;
padding: 0 30rpx;
height: 100rpx;
margin: 14rpx 0;
border-radius: 25rpx;
background: rgba(255, 255, 255, 0.9);
border: 2rpx solid transparent;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
&.focused {
border-color: $im-color-primary;
box-shadow: 0 8rpx 32rpx rgba($im-color-primary, 0.15);
transform: translateY(-2rpx);
}
.icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
margin-right: 30rpx;
border-radius: 50%;
background: $im-bg-active;
transition: all 0.3s ease;
.icon {
font-size: 32rpx;
color: $im-color-primary;
font-weight: bold;
}
}
&.focused .icon-wrapper {
transform: scale(1.1);
}
.input {
flex: 1;
font-size: 32rpx;
color: #333;
background: transparent;
border: none;
outline: none;
&::placeholder {
color: $im-text-color-light;
font-size: 30rpx;
}
}
.icon-suffix {
font-size: 36rpx;
padding: 10rpx;
}
}
}
.btn-submit {
margin-top: 80rpx;
//
.submit-btn {
height: 100rpx;
border-radius: 50rpx;
border: none;
box-shadow: 0 8rpx 32rpx rgba($im-color-primary, 0.3);
transition: all 0.3s ease;
overflow: hidden;
position: relative;
width: 100%;
margin-top: 50rpx;
&:active {
transform: translateY(2rpx);
box-shadow: 0 4rpx 16rpx rgba($im-color-primary, 0.4);
}
.btn-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: white;
font-size: $im-font-size-large;
font-weight: 600;
.btn-text {
margin-right: 10rpx;
}
}
}
//
.nav-tool-bar {
padding: 40rpx 0 60rpx;
display: flex;
align-items: center;
justify-content: center;
.nav-login {
position: fixed;
width: 100%;
bottom: 100rpx;
.login-link {
display: flex;
align-items: center;
text-decoration: none;
.login-text {
color: $im-text-color-light;
font-size: $im-font-size-small;
margin-right: 8rpx;
}
.login-highlight {
color: $im-color-primary;
text-align: center;
font-size: 32rpx;
font-size: $im-font-size-small;
font-weight: 600;
transition: all 0.3s ease;
&:active {
opacity: 0.7;
}
}
}
}
}
}
</style>
Loading…
Cancel
Save