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-iconref="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.idthis.name = loginResult.data.namethis.token = loginResult.data.token...}}
})export default useLoginStore
pinia中的数据一刷新就会消失,下一章节将会解决该问题。
6.定义IAccount对象类型
在上面很多文件里面都用到了一个对象,里面包含有账号和密码,但给它的类型都是any:
这样子是不好的。我们可以把account的类型提取出来,放在一个文件中。
在src中新建一个types文件夹:
types/login.ts:
export interface IAccount {name: stringpassword: string
}
types/index.ts:
export * from './login'
然后在需要的文件中引入: