vue3使用el-form实现登录、注册功能,且进行表单验证(Element Plus中的el-form)

简介:Element Plus 中的 el-form 是一个表单组件,用于快速构建表单并进行数据校验。它提供了丰富的表单元素和验证规则,使表单开发变得更加简单和高效。可以搭配el-dialog实现当前页面的登录、注册页 ,这两天在vue3中用到了表单登录,特意记录一下,这里没有封装,直接使用的。

效果:

1、登录页面,弹出框表单

javascript 复制代码
<el-dialog v-model="dialogFormVisible" class="poup_box">

  <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">

          <el-tab-pane label="登录" name="login_one">
            <el-form ref="ruleFormRef" :model="loginForm" :rules="loginRules" class="login_one">
              <el-form-item label="用户" prop="username" v-if="loginStatus">
                <el-input clearable v-model="loginForm.username" autocomplete="off" placeholder="请输入用户名" />
              </el-form-item>
              <el-form-item label="邮箱" prop="email" v-else>
                <el-input v-model="loginForm.email" autocomplete="off" placeholder="请输入邮箱" />
              </el-form-item>
              <el-form-item label="密码" prop="password">
                <el-input v-model="loginForm.password" type="password" show-password autocomplete="off"
                  placeholder="请输入密码" />
              </el-form-item>
              <el-form-item class="forget_item">
                <div @click="changeEmail">
                  <span v-if="loginStatus">邮箱登录</span>
                  <span v-else>用户名登录</span>
                </div>
              </el-form-item>
              <el-form-item class="checks_box">
                <el-checkbox v-model="checked1" size="large" class="checks_inpt" />
                <div class="checks_text">
                  <span>我已阅读并同意</span>
                  <b @click="changeAgreement">服务条款、</b>
                  <b>隐私政策</b>
                </div>
                <div class="userDeal" v-if="userDeal">请阅读并同意协议</div>
              </el-form-item>
              <el-form-item class="login_item">
                <el-button @click="userLogin(ruleFormRef)" :loading="isLoading">
                  <span v-if="isLoading">登录中......</span>
                  <span v-else>登录</span>
                </el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>

          <el-tab-pane label="注册" name="register_two">
            <el-form ref="ruleFormRef2" :model="registerForm" :rules="registerRules" class="register_two">
              <el-form-item label="用户" prop="username">
                <el-input clearable v-model="registerForm.username" autocomplete="off" placeholder="请输入用户名" />
              </el-form-item>
              <el-form-item label="邮箱" prop="email">
                <el-input v-model="registerForm.email" autocomplete="off" placeholder="请输入邮箱" />
              </el-form-item>
              <el-form-item label="密码" prop="password">
                <el-input v-model="registerForm.password" type="password" show-password autocomplete="off"
                  placeholder="密码由字母、数字或符号组成" />
              </el-form-item>
              <el-form-item label="邮箱验证码" prop="smsCode" class="auth_code">
                <el-input v-model="registerForm.smsCode" autocomplete="off" placeholder="请输入验证码" />
                <div class="auth_text">
                  <span @click="getAuthCode(ruleFormRef2)" v-if="authCodeNum">获取验证码</span>
                  <span class="auth_time" v-else>{{ registerNum }}秒后重发</span>
                </div>
              </el-form-item>
              <el-form-item class="checks_box">
                <el-checkbox v-model="registerCks" size="large" class="checks_inpt" />
                <div class="checks_text">
                  <span>我已阅读并同意</span>
                  <b @click="changeAgreement">服务条款、</b>
                  <b>隐私政策</b>
                </div>
                <div class="userDeal" v-if="registerDeal">请阅读并同意协议</div>
              </el-form-item>
              <el-form-item class="login_item register_item">
                <el-button @click="registerUser(ruleFormRef2)">注册</el-button>
              </el-form-item>
            </el-form>
          </el-tab-pane>

  </el-tabs>

</el-dialog>

2、相关参数,多去少补

javascript 复制代码
import { ElMessage } from 'element-plus'
//import { ref,reactive,toRefs,computed } from 'vue';
//import { useStore } from 'vuex';
import { useRouter, useRoute } from 'vue-router';
//const store = useStore();
const router = useRouter();
//const route = useRoute();
//const state = reactive({});
import { reactive, ref, onMounted } from 'vue';
import func from 'vue-temp/vue-editor-bridge';

const loginStatus = ref(true);//用户/邮箱
const isLoading = ref(false); //按钮loading  
import type { FormInstance, FormRules } from 'element-plus';
const ruleFormRef = ref<FormInstance>()
const ruleFormRef2 = ref<FormInstance>()
// 用户登录还是邮箱登录
function changeEmail() {
  loginStatus.value = !loginStatus.value;
}
// 登录
const loginForm = reactive({
  code: "",
  email: "",
  password: "",
  smsCode: "",
  username: "",
  uuid: ""
})
const loginRules = reactive({
  username: [
    {
      required: true,
      message: '用户名为4~16字符之间(中文、字母、数字或下划线)',
      min: 6, max: 18,
      trigger: 'blur',
    },],
  email: [
    { required: true, message: '请填写正确的邮箱格式', trigger: 'blur' },
    { min: 6, max: 18, message: '邮箱字符为6~18之间', trigger: 'blur' },
  ],
  password: [
    {
      required: true,
      message: '密码为6~18位字母、数字和符号',
      min: 6, max: 18,
      trigger: 'blur',
    },
    // { min: 6, max: 18, message: '密码字符为6~18之间', trigger: 'blur' },
  ],
})
// 注册
const registerForm = reactive({
  code: "",
  email: "",
  password: "",
  smsCode: "",
  username: "",
  uuid: ""
})
const registerRules = reactive({
  username: [
    { required: true, message: '用户名为4~16位之间字符', trigger: 'blur', },
    { min: 4, max: 16, message: '4~16位中文、字母、数字或下划线', trigger: 'blur' },
  ],
  email: [
    { required: true, message: '请填写正确的邮箱格式', trigger: 'blur' },
    { min: 6, max: 18, message: '邮箱为6~18位之间字符', trigger: 'blur' },
  ],
  password: [
    {
      required: true,
      message: '密码为6~18位字符,必须包含字母、数字和符号',
      min: 6, max: 18,
      trigger: 'blur',
    },
  ],
  smsCode: [
    {
      required: true,
      message: '请输入验证码',
      trigger: 'blur',
    },
  ],
})
const checked1 = ref(false);//登录协议
const userDeal = ref(false);//提示用户
const registerCks = ref(false);//注册协议
const registerDeal = ref(false);//注册状态
const authInfo = reactive({})//注册uuid
//登录信息
const loginInfo = reactive({})
// const formLoading = ref(false);
//弹框默认
const dialogFormVisible = ref(false);
//tab默认选中
const activeName = ref('login_one')
//注册/登录
const loginOrRetister = ref(true);
//验证码时间
const registerNum = ref(180);
//文字还是验证码
const authCodeNum = ref(true);

3、事件方法

javascript 复制代码
<script setup lang='ts'>

// tab切换事件
function handleClick(tab, event) {
  const iAgree = document.querySelector(".form_footer");
  if (activeName.value === "register_two") {// 注册
    loginOrRetister.value = true;
    iAgree.style.display = "none";
  } else if (activeName.value === "login_one") {// 登录
    loginOrRetister.value = false;
    iAgree.style.display = "block";
  }
}

// 右上角注册/登录状态切换
function choseResgister() {
  if (loginOrRetister.value === true) {
    loginOrRetister.value = false;
    activeName.value = "register_two";
  } else if (loginOrRetister.value === false) {
    loginOrRetister.value = true;
    activeName.value = "login_one";
  }
}

</script>

这里的Element Plus组件使用的全局引入,所以可以直接使用;

样式大家自己写下吧!

然后点击登录、注册时,表单里的输入框验证,也有做,但是有时管用,有时不管用,这里给大家文档地址,自己看吧!

**表单验证https://element-plus.org/zh-CN/component/form.html#%E8%A1%A8%E5%8D%95%E6%A0%A1%E9%AA%8C**​​​​​​​

表单校验详情页https://element-plus.run/#eyJzcmMvQXBwLnZ1ZSI6Ijx0ZW1wbGF0ZT5cbiAgPGVsLWZvcm1cbiAgICByZWY9XCJydWxlRm9ybVJlZlwiXG4gICAgOm1vZGVsPVwicnVsZUZvcm1cIlxuICAgIDpydWxlcz1cInJ1bGVzXCJcbiAgICBsYWJlbC13aWR0aD1cIjEyMHB4XCJcbiAgICBjbGFzcz1cImRlbW8tcnVsZUZvcm1cIlxuICAgIDpzaXplPVwiZm9ybVNpemVcIlxuICAgIHN0YXR1cy1pY29uXG4gID5cbiAgICA8ZWwtZm9ybS1pdGVtIGxhYmVsPVwiQWN0aXZpdHkgbmFtZVwiIHByb3A9XCJuYW1lXCI+XG4gICAgICA8ZWwtaW5wdXQgdi1tb2RlbD1cInJ1bGVGb3JtLm5hbWVcIiAvPlxuICAgIDwvZWwtZm9ybS1pdGVtPlxuICAgIDxlbC1mb3JtLWl0ZW0gbGFiZWw9XCJBY3Rpdml0eSB6b25lXCIgcHJvcD1cInJlZ2lvblwiPlxuICAgICAgPGVsLXNlbGVjdCB2LW1vZGVsPVwicnVsZUZvcm0ucmVnaW9uXCIgcGxhY2Vob2xkZXI9XCJBY3Rpdml0eSB6b25lXCI+XG4gICAgICAgIDxlbC1vcHRpb24gbGFiZWw9XCJab25lIG9uZVwiIHZhbHVlPVwic2hhbmdoYWlcIiAvPlxuICAgICAgICA8ZWwtb3B0aW9uIGxhYmVsPVwiWm9uZSB0d29cIiB2YWx1ZT1cImJlaWppbmdcIiAvPlxuICAgICAgPC9lbC1zZWxlY3Q+XG4gICAgPC9lbC1mb3JtLWl0ZW0+XG4gICAgPGVsLWZvcm0taXRlbSBsYWJlbD1cIkFjdGl2aXR5IGNvdW50XCIgcHJvcD1cImNvdW50XCI+XG4gICAgICA8ZWwtc2VsZWN0LXYyXG4gICAgICAgIHYtbW9kZWw9XCJydWxlRm9ybS5jb3VudFwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiQWN0aXZpdHkgY291bnRcIlxuICAgICAgICA6b3B0aW9ucz1cIm9wdGlvbnNcIlxuICAgICAgLz5cbiAgICA8L2VsLWZvcm0taXRlbT5cbiAgICA8ZWwtZm9ybS1pdGVtIGxhYmVsPVwiQWN0aXZpdHkgdGltZVwiIHJlcXVpcmVkPlxuICAgICAgPGVsLWNvbCA6c3Bhbj1cIjExXCI+XG4gICAgICAgIDxlbC1mb3JtLWl0ZW0gcHJvcD1cImRhdGUxXCI+XG4gICAgICAgICAgPGVsLWRhdGUtcGlja2VyXG4gICAgICAgICAgICB2LW1vZGVsPVwicnVsZUZvcm0uZGF0ZTFcIlxuICAgICAgICAgICAgdHlwZT1cImRhdGVcIlxuICAgICAgICAgICAgbGFiZWw9XCJQaWNrIGEgZGF0ZVwiXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlBpY2sgYSBkYXRlXCJcbiAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCVcIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvZWwtZm9ybS1pdGVtPlxuICAgICAgPC9lbC1jb2w+XG4gICAgICA8ZWwtY29sIGNsYXNzPVwidGV4dC1jZW50ZXJcIiA6c3Bhbj1cIjJcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWdyYXktNTAwXCI+LTwvc3Bhbj5cbiAgICAgIDwvZWwtY29sPlxuICAgICAgPGVsLWNvbCA6c3Bhbj1cIjExXCI+XG4gICAgICAgIDxlbC1mb3JtLWl0ZW0gcHJvcD1cImRhdGUyXCI+XG4gICAgICAgICAgPGVsLXRpbWUtcGlja2VyXG4gICAgICAgICAgICB2LW1vZGVsPVwicnVsZUZvcm0uZGF0ZTJcIlxuICAgICAgICAgICAgbGFiZWw9XCJQaWNrIGEgdGltZVwiXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlBpY2sgYSB0aW1lXCJcbiAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCVcIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvZWwtZm9ybS1pdGVtPlxuICAgICAgPC9lbC1jb2w+XG4gICAgPC9lbC1mb3JtLWl0ZW0+XG4gICAgPGVsLWZvcm0taXRlbSBsYWJlbD1cIkluc3RhbnQgZGVsaXZlcnlcIiBwcm9wPVwiZGVsaXZlcnlcIj5cbiAgICAgIDxlbC1zd2l0Y2ggdi1tb2RlbD1cInJ1bGVGb3JtLmRlbGl2ZXJ5XCIgLz5cbiAgICA8L2VsLWZvcm0taXRlbT5cbiAgICA8ZWwtZm9ybS1pdGVtIGxhYmVsPVwiQWN0aXZpdHkgdHlwZVwiIHByb3A9XCJ0eXBlXCI+XG4gICAgICA8ZWwtY2hlY2tib3gtZ3JvdXAgdi1tb2RlbD1cInJ1bGVGb3JtLnR5cGVcIj5cbiAgICAgICAgPGVsLWNoZWNrYm94IGxhYmVsPVwiT25saW5lIGFjdGl2aXRpZXNcIiBuYW1lPVwidHlwZVwiIC8+XG4gICAgICAgIDxlbC1jaGVja2JveCBsYWJlbD1cIlByb21vdGlvbiBhY3Rpdml0aWVzXCIgbmFtZT1cInR5cGVcIiAvPlxuICAgICAgICA8ZWwtY2hlY2tib3ggbGFiZWw9XCJPZmZsaW5lIGFjdGl2aXRpZXNcIiBuYW1lPVwidHlwZVwiIC8+XG4gICAgICAgIDxlbC1jaGVja2JveCBsYWJlbD1cIlNpbXBsZSBicmFuZCBleHBvc3VyZVwiIG5hbWU9XCJ0eXBlXCIgLz5cbiAgICAgIDwvZWwtY2hlY2tib3gtZ3JvdXA+XG4gICAgPC9lbC1mb3JtLWl0ZW0+XG4gICAgPGVsLWZvcm0taXRlbSBsYWJlbD1cIlJlc291cmNlc1wiIHByb3A9XCJyZXNvdXJjZVwiPlxuICAgICAgPGVsLXJhZGlvLWdyb3VwIHYtbW9kZWw9XCJydWxlRm9ybS5yZXNvdXJjZVwiPlxuICAgICAgICA8ZWwtcmFkaW8gbGFiZWw9XCJTcG9uc29yc2hpcFwiIC8+XG4gICAgICAgIDxlbC1yYWRpbyBsYWJlbD1cIlZlbnVlXCIgLz5cbiAgICAgIDwvZWwtcmFkaW8tZ3JvdXA+XG4gICAgPC9lbC1mb3JtLWl0ZW0+XG4gICAgPGVsLWZvcm0taXRlbSBsYWJlbD1cIkFjdGl2aXR5IGZvcm1cIiBwcm9wPVwiZGVzY1wiPlxuICAgICAgPGVsLWlucHV0IHYtbW9kZWw9XCJydWxlRm9ybS5kZXNjXCIgdHlwZT1cInRleHRhcmVhXCIgLz5cbiAgICA8L2VsLWZvcm0taXRlbT5cbiAgICA8ZWwtZm9ybS1pdGVtPlxuICAgICAgPGVsLWJ1dHRvbiB0eXBlPVwicHJpbWFyeVwiIEBjbGljaz1cInN1Ym1pdEZvcm0ocnVsZUZvcm1SZWYpXCI+XG4gICAgICAgIENyZWF0ZVxuICAgICAgPC9lbC1idXR0b24+XG4gICAgICA8ZWwtYnV0dG9uIEBjbGljaz1cInJlc2V0Rm9ybShydWxlRm9ybVJlZilcIj5SZXNldDwvZWwtYnV0dG9uPlxuICAgIDwvZWwtZm9ybS1pdGVtPlxuICA8L2VsLWZvcm0+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0IGxhbmc9XCJ0c1wiIHNldHVwPlxuaW1wb3J0IHsgcmVhY3RpdmUsIHJlZiB9IGZyb20gJ3Z1ZSdcbmltcG9ydCB0eXBlIHsgRm9ybUluc3RhbmNlLCBGb3JtUnVsZXMgfSBmcm9tICdlbGVtZW50LXBsdXMnXG5cbmludGVyZmFjZSBSdWxlRm9ybSB7XG4gIG5hbWU6IHN0cmluZ1xuICByZWdpb246IHN0cmluZ1xuICBjb3VudDogc3RyaW5nXG4gIGRhdGUxOiBzdHJpbmdcbiAgZGF0ZTI6IHN0cmluZ1xuICBkZWxpdmVyeTogYm9vbGVhblxuICB0eXBlOiBzdHJpbmdbXVxuICByZXNvdXJjZTogc3RyaW5nXG4gIGRlc2M6IHN0cmluZ1xufVxuXG5jb25zdCBmb3JtU2l6ZSA9IHJlZignZGVmYXVsdCcpXG5jb25zdCBydWxlRm9ybVJlZiA9IHJlZjxGb3JtSW5zdGFuY2U+KClcbmNvbnN0IHJ1bGVGb3JtID0gcmVhY3RpdmU8UnVsZUZvcm0+KHtcbiAgbmFtZTogJ0hlbGxvJyxcbiAgcmVnaW9uOiAnJyxcbiAgY291bnQ6ICcnLFxuICBkYXRlMTogJycsXG4gIGRhdGUyOiAnJyxcbiAgZGVsaXZlcnk6IGZhbHNlLFxuICB0eXBlOiBbXSxcbiAgcmVzb3VyY2U6ICcnLFxuICBkZXNjOiAnJyxcbn0pXG5cbmNvbnN0IHJ1bGVzID0gcmVhY3RpdmU8Rm9ybVJ1bGVzPFJ1bGVGb3JtPj4oe1xuICBuYW1lOiBbXG4gICAgeyByZXF1aXJlZDogdHJ1ZSwgbWVzc2FnZTogJ1BsZWFzZSBpbnB1dCBBY3Rpdml0eSBuYW1lJywgdHJpZ2dlcjogJ2JsdXInIH0sXG4gICAgeyBtaW46IDMsIG1heDogNSwgbWVzc2FnZTogJ0xlbmd0aCBzaG91bGQgYmUgMyB0byA1JywgdHJpZ2dlcjogJ2JsdXInIH0sXG4gIF0sXG4gIHJlZ2lvbjogW1xuICAgIHtcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgbWVzc2FnZTogJ1BsZWFzZSBzZWxlY3QgQWN0aXZpdHkgem9uZScsXG4gICAgICB0cmlnZ2VyOiAnY2hhbmdlJyxcbiAgICB9LFxuICBdLFxuICBjb3VudDogW1xuICAgIHtcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgbWVzc2FnZTogJ1BsZWFzZSBzZWxlY3QgQWN0aXZpdHkgY291bnQnLFxuICAgICAgdHJpZ2dlcjogJ2NoYW5nZScsXG4gICAgfSxcbiAgXSxcbiAgZGF0ZTE6IFtcbiAgICB7XG4gICAgICB0eXBlOiAnZGF0ZScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIG1lc3NhZ2U6ICdQbGVhc2UgcGljayBhIGRhdGUnLFxuICAgICAgdHJpZ2dlcjogJ2NoYW5nZScsXG4gICAgfSxcbiAgXSxcbiAgZGF0ZTI6IFtcbiAgICB7XG4gICAgICB0eXBlOiAnZGF0ZScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIG1lc3NhZ2U6ICdQbGVhc2UgcGljayBhIHRpbWUnLFxuICAgICAgdHJpZ2dlcjogJ2NoYW5nZScsXG4gICAgfSxcbiAgXSxcbiAgdHlwZTogW1xuICAgIHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgIG1lc3NhZ2U6ICdQbGVhc2Ugc2VsZWN0IGF0IGxlYXN0IG9uZSBhY3Rpdml0eSB0eXBlJyxcbiAgICAgIHRyaWdnZXI6ICdjaGFuZ2UnLFxuICAgIH0sXG4gIF0sXG4gIHJlc291cmNlOiBbXG4gICAge1xuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICBtZXNzYWdlOiAnUGxlYXNlIHNlbGVjdCBhY3Rpdml0eSByZXNvdXJjZScsXG4gICAgICB0cmlnZ2VyOiAnY2hhbmdlJyxcbiAgICB9LFxuICBdLFxuICBkZXNjOiBbXG4gICAgeyByZXF1aXJlZDogdHJ1ZSwgbWVzc2FnZTogJ1BsZWFzZSBpbnB1dCBhY3Rpdml0eSBmb3JtJywgdHJpZ2dlcjogJ2JsdXInIH0sXG4gIF0sXG59KVxuXG5jb25zdCBzdWJtaXRGb3JtID0gYXN5bmMgKGZvcm1FbDogRm9ybUluc3RhbmNlIHwgdW5kZWZpbmVkKSA9PiB7XG4gIGlmICghZm9ybUVsKSByZXR1cm5cbiAgYXdhaXQgZm9ybUVsLnZhbGlkYXRlKCh2YWxpZCwgZmllbGRzKSA9PiB7XG4gICAgaWYgKHZhbGlkKSB7XG4gICAgICBjb25zb2xlLmxvZygnc3VibWl0IScpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCdlcnJvciBzdWJtaXQhJywgZmllbGRzKVxuICAgIH1cbiAgfSlcbn1cblxuY29uc3QgcmVzZXRGb3JtID0gKGZvcm1FbDogRm9ybUluc3RhbmNlIHwgdW5kZWZpbmVkKSA9PiB7XG4gIGlmICghZm9ybUVsKSByZXR1cm5cbiAgZm9ybUVsLnJlc2V0RmllbGRzKClcbn1cblxuY29uc3Qgb3B0aW9ucyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IDEwMDAwIH0pLm1hcCgoXywgaWR4KSA9PiAoe1xuICB2YWx1ZTogYCR7aWR4ICsgMX1gLFxuICBsYWJlbDogYCR7aWR4ICsgMX1gLFxufSkpXG48L3NjcmlwdD5cbiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHt9XG59IiwidHNjb25maWcuanNvbiI6IntcbiAgXCJjb21waWxlck9wdGlvbnNcIjoge1xuICAgIFwiYWxsb3dKc1wiOiB0cnVlLFxuICAgIFwiY2hlY2tKc1wiOiB0cnVlLFxuICAgIFwianN4XCI6IFwicHJlc2VydmVcIixcbiAgICBcInRhcmdldFwiOiBcIkVTTmV4dFwiLFxuICAgIFwibW9kdWxlXCI6IFwiRVNOZXh0XCIsXG4gICAgXCJtb2R1bGVSZXNvbHV0aW9uXCI6IFwiQnVuZGxlclwiLFxuICAgIFwiYWxsb3dJbXBvcnRpbmdUc0V4dGVuc2lvbnNcIjogdHJ1ZSxcbiAgICBcInR5cGVzXCI6IFtcImVsZW1lbnQtcGx1cy9nbG9iYWwuZC50c1wiXVxuICB9LFxuICBcInZ1ZUNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAgXCJ0YXJnZXRcIjogMy4zXG4gIH1cbn1cbiIsIl9vIjp7fX0=

相关推荐
dsyyyyy11014 小时前
JavaScript变量
开发语言·javascript·ecmascript
kyriewen5 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
胡志辉的博客6 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖6 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty7 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚7 小时前
软件测试期末考试
vue.js
小二·7 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜8 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain5098 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年2759 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax