10vue3实战-----实现登录的基本功能
- 1.基本页面的搭建
- 2.账号登录的验证规则配置
- 3.点击登录按钮
- 4.表单的校验
- 5.账号的登录逻辑和登录状态保存
- 6.定义IAccount对象类型
1.基本页面的搭建
大概需要搭建成这样子的页面:
具体的搭建界面就不多讲。各个项目都有自己的登录界面,搭建方法大同小异,这是基础,在这不做赘叙。
2.账号登录的验证规则配置
直接使用element-plus中现成的表单校验功能。
template:
<template>
<div class="pane-account">
<el-form
:model="account"
:rules="accountRules"
label-width="60px"
size="large"
status-icon
ref="formRef"
>
<el-form-item label="帐号" prop="name">
<el-input v-model="account.name" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="account.password" show-password />
</el-form-item>
</el-form>
</div>
</template>
script:
<script setup lang="ts">
import { reactive} from 'vue'
import type { FormRules} from 'element-plus'
// 1.定义account数据
const account = reactive({
name: '',
password: ''
})
// 2.定义校验规则
//这里accountRules不需要用reactive进行响应式,因为一般不会改变。
const accountRules: FormRules = {
name: [
{ required: true, message: '必须输入帐号信息~', trigger: 'blur' },
{
pattern: /^[a-z0-9]{6,20}$/,
message: '必须是6~20数字或字母组成~',
trigger: 'blur'
}
],
password: [
{ required: true, message: '必须输入密码信息~', trigger: 'blur' },
{
pattern: /^[a-z0-9]{3,}$/,
message: '必须是3位以上数字或字母组成',
trigger: 'blur'
}
]
}
</script>
3.点击登录按钮
上面的登录界面把它封装成了多个组件。登录模块目录结构如下:
如上,Login.vue有一个login-panel登录面板子组件,登录面板组件下有pane-account和pane-phone两个子组件。
这里“立即登录”按钮是在login-panel组件中,点击按钮后需要用到账号和密码的信息,但他们都在子组件。有一种方法是把子组件传到父组件;还有一种方法是login-panel父组件中调用子组件的方法。这里我用第二种方法:
以账号登录为例,子组件pane-account文件:
<script setup lang="ts">
import { reactive, ref } from 'vue'
// 1.定义account数据
const account = reactive({
name: '',
password: ''
})
...
// 3.执行帐号的登录逻辑
function loginAction() {
console.log("用户正在登录",account.name,account.password);
}
//一定要暴露出来,父组件才能使用子组件的方法:
defineExpose({
loginAction
})
</script>
父组件login-panel.vue文件:
<script setup lang="ts">
import { ref } from 'vue'
import PaneAccount from './pane-account.vue'
import PanePhone from './pane-phone.vue'
const activeName = ref('account')
//下面这行代码要特别注意,经常会用到
//一般都是用InstanceType<typeof xxx>这种方法
//这里最好不要const accountRef = ref<any>()
//虽然万事都可以any,但那样子的话就没有相关提示了
const accountRef = ref<InstanceType<typeof PaneAccount>>()
//点击登录按钮
function handleLoginBtnClick() {
if (activeName.value === 'account') {
//简写方式,accountRef存在才执行accountRef.value.loginAction()
accountRef.value?.loginAction()
} else {
console.log('用户在进行手机登录')
}
}
</script>
4.表单的校验
子组件pane-account文件:
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { FormRules, ElForm } from 'element-plus'
// 1.定义account数据
const account = reactive({
name: '',
password: ''
})
...
// 3.执行帐号的登录逻辑
//这个与上面的accountRef是一样的道理
const formRef = ref<InstanceType<typeof ElForm>>()
function loginAction() {
formRef.value?.validate((valid) => {
if (valid) {
console.log("验证成功","登录的操作")
} else {
ElMessage.error('Oops, 请您输入正确的格式后再操作~~.')
}
})
}
defineExpose({
loginAction
})
</script>
5.账号的登录逻辑和登录状态保存
首先要封装一下登录的网络接口:
在service文件夹中新建main和login模块:
service/login/login.ts:
import hyRequest from '..'
//这里account类型暂时为any,后面再处理
export function accountLoginRequest(account: any) {
return hyRequest.post({
url: '/login',
data: account
})
}
登录之后需要把用户信息保存到pinia中,所以在store里面也要新建login和main模块来处理相关业务:
store/login/login.ts:
import { defineStore } from 'pinia'
import { accountLoginRequest } from '@/service/login/login'
const useLoginStore = defineStore('login', {
state: () => ({
id: '',
token:'',
name: ''
}),
actions: {
//account暂时为any,后面会再进行处理
async loginAccountAction(account: any) {
// 1.账号登录, 获取token等信息
const loginResult = await accountLoginRequest(account)
this.id = loginResult.data.id
this.name = loginResult.data.name
this.token = loginResult.data.token
...
}
}
})
export default useLoginStore
pinia中的数据一刷新就会消失,下一章节将会解决该问题。
6.定义IAccount对象类型
在上面很多文件里面都用到了一个对象,里面包含有账号和密码,但给它的类型都是any:
这样子是不好的。我们可以把account的类型提取出来,放在一个文件中。
在src中新建一个types文件夹:
types/login.ts:
export interface IAccount {
name: string
password: string
}
types/index.ts:
export * from './login'
然后在需要的文件中引入: