(十二)Vue3-huohuo-admin 登录模块进阶

894 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天

登录模块进阶

前面我们做了一个比较基础的登录 UI,现在我们再来给他增加一些常用的功能及业务流。

基础登录完善

登录模块我们通常会选择 UI 框架的表单组件(比如EPel-formel-form-item)搭配输入框和按钮(el-inputel-button)作为基架。既能帮助我们美化页面元素(方便地引入图标),又能帮助我们提升用户的体验(数据编辑的便捷性)。

图标加入

  • el-input组件的prefix-icon属性与show-password属性
  • remixicon图标库使用
  • useRenderIcon图标渲染hook

image-20220526195938598

这时候你可能会觉得这个输入框显得有点小气了,我们利用el-formsize属性将表单整体放大一些。

image-20220526200226357

是不是好看多了 ~

验证码

验证码我们可以插入输入框中,即使用el-input的插槽,将图形验证码组件ReImageVerify插入(组件详解后续会编写)。

image-20220526200818120

<Motion :delay="200">
  <el-form-item>
    <el-input
      clearable
      placeholder="验证码"
      :prefix-icon="
        useRenderIcon('ri:shield-keyhole-line', { online: true })
      "
    >
      <template v-slot:append>
        <ReImageVerify v-model:code="imgCode" />
      </template>
    </el-input>
  </el-form-item>
</Motion>

这里提一嘴组件声明的问题:我们在对自己封装的组件添加name标识的时候,需要在.vue 文件中定义两个script 标签,一个用来定义组件的name,一个用来编写组件逻辑。我想你肯定跟我一样,是不太能接受这种有点“多此一举”的写法的。不过我想找个问题vue官方应该会在后续解决掉的,这里我们使用一个大佬开发的插件来帮我们解决找个问题。

image-20220526203717624

unplugin-vue-define-options 插件

安装

pnpm install unplugin-vue-define-options -D

在 vite 中引入

image-20220526204316795

我们的项目时 TS 项目,所以也需要同时适配tsconfig.json

{
  "types": [
    "node",
    "vite/client",
    "element-plus/global",
    "unplugin-vue-define-options"
  ]
}

使用

<script setup lang="ts">
defineOptions({
  name: "test",
});
</script>

如果你想要封装一个组件库,那么这个插件就会很有用了......

然后我们来看一下效果

image-20220527145802491

发现样式好像不太对,应该把两边的padding去掉。这是EP自带的默认样式,所以我们需要打开浏览器控制台,找到对应的样式并修改——使用:deep来实现。

image-20220527150257818

<style lang="scss" scoped>
:deep(.el-input-group__append, .el-input-group__prepend) {
  padding: 0;
}
</style>

多渠道登录

其他渠道登录包括:

  • 手机登录
  • 二维码登录
  • 第三方登录:微信、支付宝、QQ、微博等

常用的 ReIcon 组件 Bug

看一下效果:

image-20220527153248570

我们发现第三方登录的内容不见了?怎么回事?仔细看,其中我们使用了IconifyIconOnline组件,是它没有生效,而且我们发现这个组件在浏览器中是红色的。

我们先来看看这个红色

image-20220527162754792

TS找不到这个类型,无法为我们做提示,所以我们需要给它做个全局声明

image-20220527163035870

我们把这个组件引入login代码中看看

image-20220527153606348

发现,生效了,这是为什么呢?既然引入才有效,说明这个组件不是全局组件呢。像这种可能频繁用到的组件,我不想每次都手动引入,怎么办呢?

这不就回到了组件的全局注册吗

一般来说,我们不会把每个组件都全局注册(除非你在做组件库),多数情况下我们会进行手动引入自己封装的组件,因为用的不频繁。所以我们有必要单独为全局组件做处理。

src/components文件下新建一个全局组件注册文件registerGlobComp.ts

// 全局注册的组件 src\components\registerGlobComp.ts
import type { App } from "vue";
import { withInstall } from "/@/utils/withInstall";
import iconifyIconOnline from "./ReIcon/src/iconifyIconOnline";

export const IconifyIconOnline = withInstall(iconifyIconOnline);

export function registerGlobComp(app: App) {
  app.use(IconifyIconOnline);
}

main.ts中再引入,并时刻保持写注释的习惯哦!大功告成!

image-20220527172444087

表单验证

首先我们要明确的是,我们应该遵循EP表单规则做验证,并捋清楚相关要点。

  • 确定需要做验证的表单:通过ref拿到表单DOM元素,在rules属性中填充配置规则
  • 确定需要做验证的表单选项:表单(prop)与输入框数据(v-model)绑定,以协助验证
  • 制定验证规则:一般规则、validator规则(规则的制定我们另起文件utils.rule.ts编写,再引入)

image-20220527174428568

image-20220527181233497

其他的表单开发如手机登录、忘记密码、注册基本和登录相同,这里就不再描述,大家可以自行查看源码。

二维码组件问题

项目中该组件使用了tsx语法开发,所以我们需要让项目支持tsx语法。

官方推荐我们使用@vue/babel-plugin-jsx插件来支持jsx/tsx语法,但是我们使用的是Vite,就不是用这个插件啦。应使用官方提供的@vitejs/plugin-vue-jsx插件,它提供了Vue 3特性的支持,包括 HMR、全局组件解析、指令和插槽。

pnpm install @vitejs/plugin-vue-jsx -D

然后在我们的vite插件文件中引入即可

登录操作

一个方法就可以描述清楚基本的登录的逻辑

const onLogin = async (formEl: FormInstance | undefined) => {
  loading.value = true; // 登录loading激活
  if (!formEl) return; // 确定是表单登录
  // 表单数据规则验证
  await formEl.validate((valid, fields) => {
    if (valid) {
      // 模拟请求(实际会在这里执行一个登录请求,一般请求成功后返回info数据)
      setTimeout(() => {
        loading.value = false; // 登录loading取消
        // 将登录成功返回的info数据存入session
        storageSession.setItem("info", {
          username: "admin",
          accessToken: "eyJhbGciOiJIUzUxMiJ9.test",
        });
        // 根据info信息,初始化项目路由(路由权限控制)
        initRouter("admin").then(() => {});
        ElMessage.success("登陆成功"); // 优化体验
        router.push("/"); // 登录成功后跳转到指定路由
      }, 2000);
    } else {
      loading.value = false; // 登录loading取消
      return fields;
    }
  });
};

登录表单切换

各个表单之间的切换由currentPage来控制,每次点击都会将currentPage的值改变,并存入store中。

  • 0: 登录表单
  • 1: 手机号登陆表单
  • 2: 二维码登陆表单
  • 3: 注册表单
  • 4: 忘记密码表单

image-20220527233252676

效果示例:

image-20220527232207408

注册表单:

image-20220527232358853