vue3_ts setup语法糖做一个登录注册

简介: vue3_ts setup语法糖做一个登录注册

@[TOC]

背景

vue3 ts 搭建一个简单的登录系统平台
个人后台管理地址:https://yongma16.xyz/back-front/#/register

效果

注册
image.png

登录
image.png

实现

ts的interface定义数据类型

interface 定义类型
form表单(用户名、密码、记住的复选框)
form校验 (用户名、密码)
state类型抛到template的变量声明

interface FormStateType {
   
   
  username: string;
  password: string;
  remember: boolean;
}
interface FormRuleType {
   
   
  username: Object;
  password: Object;
}
interface stateType {
   
   
  formState: FormStateType;
  formRule: FormRuleType;
  layoutConfig: any;
  wrapperCol: any;
  submitWrapperCol: any;
  spinning: boolean;
  backgroundImgUrl: string;
}

注意:
const定义函数和function定义函数区别
1.const 定义函数只能在函数被调用之前
2.function定义函数可以在函数被调用之后
3.setup语法糖中定义的属性变量和函数直接可以被template引用,无须return
4.setup语法糖缺少export default 的name组件名称定义(name默认为文件名)
完整代码块

<template>
    <div class="container">
      <div class="loginUser-container">
        <div class="loginUser-title">管理平台</div>
        <a-form
          :model="state.formState"
          :label-col="state.layoutConfig.labelCol"
          :wrapper-col="state.layoutConfig.wrapperCol"
          :rules="state.formRule"
          ref="formRef"
          layout="vertical"
          autocomplete="off"
        >
          <a-form-item label="账号" name="username">
            <a-input
              v-model:value="state.formState.username"
              allowClear
              placeholder="请输入账号"
              :disabled="state.spinning"
            />
          </a-form-item>

          <a-form-item label="密码" name="password">
            <a-input-password
              v-model:value="state.formState.password"
              :disabled="state.spinning"
              allowClear
              placeholder="请输入密码"
            />
          </a-form-item>

          <a-form-item name="remember" :wrapper-col="state.wrapperCol">
            <a-checkbox v-model:checked="state.formState.remember" :disabled="state.spinning"
              >记住密码</a-checkbox
            >
          </a-form-item>

          <a-form-item :wrapper-col="state.submitWrapperCol" class="submit-box">
            <a-button
              type="primary"
              html-type="submit"
              @click="loginAction"
              :loading="state.spinning"
              style="width: 100%; font-size: 16px; font-weight: bolder"
              >登录</a-button
            >
          </a-form-item>
        </a-form>
        <div class="description">
          <span class="description-prefix">没账号?</span>
          <span @click="jumpRegister" class="description-after" :disabled="state.spinning">去注册</span>
        </div>
      </div>
    </div>
</template>
<script lang="ts" setup>
import {
   
    reactive, ref, onMounted } from "vue";
import {
   
    useRouter } from "vue-router";
import {
   
    useStore } from "vuex";
import {
   
    message } from "ant-design-vue";
import {
   
    loginUser } from "../../service/user/userApi";

import type {
   
    FormInstance } from "ant-design-vue";

interface FormStateType {
   
   
  username: string;
  password: string;
  remember: boolean;
}
interface FormRuleType {
   
   
  username: Object;
  password: Object;
}
interface stateType {
   
   
  formState: FormStateType;
  formRule: FormRuleType;
  layoutConfig: any;
  wrapperCol: any;
  submitWrapperCol: any;
  spinning: boolean;
  backgroundImgUrl: string;
}
// 路由
const router = useRouter();
//store
const store = useStore();
const formRef = ref<FormInstance>();
const state: stateType = reactive({
   
   
  formState: {
   
   
    username: "",
    password: "",
    remember: false,
  },
  spinning: false,
  formRule: {
   
   
    username: [{
   
    required: true, message: "请输入账号!" }],
    password: [{
   
    required: true, message: "请输入密码!" }],
  },
  layoutConfig: {
   
   
    labelCol: {
   
   
      span: 8,
    },
    wrapperCol: {
   
   
      span: 24,
    },
  },
  wrapperCol: {
   
    offset: 0, span: 24 },
  submitWrapperCol: {
   
    offset: 0, span: 24 },
  backgroundImgUrl:
    "http://www.yongma16.xyz/staticFile/common/img/background.png",
});
/**
 * 初始化表单内容
 */
const initForm = () => {
   
   
  const userInfoItem: any = window.localStorage.getItem("userInfo");
  interface userInfoType {
   
   
    username: string;
    password: string;
    remember: boolean;
  }
  const userInfo: userInfoType = userInfoItem
    ? JSON.parse(userInfoItem)
    : {
   
   
        username: "",
        password: "",
        remember: false,
      };
  if (userInfo.username && userInfo.password) {
   
   
    state.formState.username = userInfo.username;
    state.formState.password = userInfo.password;
    state.formState.remember = userInfo.remember;
  }
};
/**
 * 前往注册!
 */
const jumpRegister = () => {
   
   
  // 带 hash,结果是 /about#team
  router.push({
   
    path: "/register" });
};

/**
 * 前往home!
 */
const jumpHome = () => {
   
   
  // 带 hash,结果是 /about#team
  router.push({
   
    path: "/" });
};
/**
 * 记住密码
 * @param params
 */
const rememberAction = (params: Object) => {
   
   
  window.localStorage.setItem("userInfo", JSON.stringify(params));
};
/**
 * 登录
 */
const loginAction = () => {
   
   
  if (formRef.value) {
   
   
    formRef.value.validate().then((res: any) => {
   
   
      state.spinning = true;
      const params = {
   
   
        username: state.formState.username,
        password: state.formState.password,
      };
      if (state.formState.remember) {
   
   
        rememberAction({
   
    ...params, remember: state.formState.remember });
      }
      loginUser(params)
        .then((res: any) => {
   
   
          console.log("res", res);
          const {
   
    data: response } = res;
          state.spinning = false;
          if (response.code === 200) {
   
   
            store.commit("user/setUserInfo", response.data);
            // 跳转
            setTimeout(() => {
              jumpHome();
            }, 500);
            message.success(response.message);
          } else {
            message.warning(response.message);
          }
        })
        .catch((r: any) => {
          state.spinning = false;
          message.error(JSON.stringify(r));
          throw Error(r);
        });
    });
  }
};

onMounted(() => {
   
   
  //初始化
  initForm();
});
</script>

结束

感谢阅读,下面是我的gitcoe代码仓库,如有问题,欢迎提出讨论!
代码仓库:https://gitcode.net/qq_38870145/springcloudfront

目录
相关文章
|
JavaScript 前端开发 API
Vue3之script-setup 语法糖
本文介绍了Vue 3的`<script setup>`语法糖,通过示例代码演示了如何在组件中使用`<script setup>`以及相关的Vue 3 Composition API函数和特性,如响应式引用、生命周期钩子、CSS模块等,并展示了组件间的通信和样式应用。
463 0
Vue3之script-setup 语法糖
|
JavaScript 前端开发 API
Vue3 中 setup 语法糖做了哪些骚操作?
Vue3 中 setup 语法糖做了哪些骚操作?
|
JavaScript
解决vue3中不支持.sync语法糖
解决vue3中不支持.sync语法糖
986 3
|
JavaScript API 开发工具
Vue3甜点探秘:史上最甜的语法糖
Vue3甜点探秘:史上最甜的语法糖
194 4
|
JavaScript 前端开发 测试技术
vue的setup语法糖?
vue的setup语法糖?
130 1
|
JavaScript
vue中setup语法糖的优点
vue中setup语法糖的优点
|
JavaScript
Vue 使用 setup 语法糖
Vue 使用 setup 语法糖
174 0
|
JavaScript
vue的sync语法糖的使用
vue的sync语法糖的使用
180 0
|
JavaScript
什么是vue的sync语法糖如何使用
什么是vue的sync语法糖如何使用
158 0
|
缓存 JavaScript 前端开发
vue3 setup语法糖 搜索
vue3 setup语法糖 搜索
126 0