山东大学软件学院项目实训weblab-3

前言

项目地址
本项目是为开发一套容器化的开发、运行、测试环境,用以支持Web开发、程序设计等课程的实验教学。

任务

实现路由限制以及注册时的表单验证

路由限制

给需要登陆状态才能进入的页面添加meta属性

import { createRouter, createWebHistory } from 'vue-router';
import codingViewVue from '../views/coding-view.vue';
import registerViewVue from '../views/register-view.vue';
import loginhomeVue from '../views/loginhome.vue';
import loginViewVue from '../views/login-view.vue';
import forgetpasswViewVue from '../views/forgetpassw-view.vue';
import updatepasswViewVue from '../views/updatepassw-view.vue';
import resetpasswViewVue from '../views/resetpassw-view.vue';

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/",
      name: "home",
      component: codingViewVue,
      meta:{
        isLogin:false,
      }
    },
    {
      path: "/register",
      name: "register-view",
      component: registerViewVue,
      meta:{
        isLogin:false,
      }
    },
    {
      path: "/login",
      name: "login-view",
      component: loginViewVue,
      meta:{
        isLogin:false,
      }
    },
    {
      path: "/logout",
      name: "coding-view",
      component: codingViewVue,
      meta:{
        isLogin:false,
      }
    },
    {
      path: "/forget_password",
      name: "forgetpassw-view",
      component: forgetpasswViewVue,
      meta:{
        isLogin:false,
      }
    },
    {
      path: "/update_password",
      name: "update_password",
      component: updatepasswViewVue,
      meta:{
        isLogin:true,
      }
    },
    {
      path: "/reset_password",
      name: "reset_password",
      component: resetpasswViewVue,
      meta:{
        isLogin:false,
      }
    },
    {
      path: "/login_home",
      name: "login_home",
      component: loginhomeVue,
      meta:{
        isLogin:true,
      }
    },
  ],
});

export default router;

利用pinia实现全局状态管理

import { defineStore } from "pinia";

export const useLoginStore = defineStore({
  id: "login",
  state: () => ({
    isLogin: Number(localStorage.getItem('isLogin') || '0'),
    userId: localStorage.getItem('userId') || '',
    userPassword: localStorage.getItem('userPassword') || '',
  }),
  getters: {
    getIsLogin(state) {
      return (state.isLogin == 1) ? true : false;
    },
    getUserId(state) {
      return state.userId;
    },
    getUserPassword(state) {
      return state.userPassword
    }

  },
  actions: {
    userLogin(id: string, pwd: string) {
      this.isLogin = 1;
      this.userId = id;
      this.userPassword = pwd;
      localStorage.setItem('isLogin', '1');
      localStorage.setItem('userId', id);
      localStorage.setItem('userPassword', pwd);
    },
    userLogout() {
      this.isLogin = 0;
      this.userId = '';
      this.userPassword = '';
      localStorage.setItem('isLogin', '0');
      localStorage.setItem('userId', '');
      localStorage.setItem('userPassword', '');
    }
  },
});

main.ts中实现路由限制

import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
import ElementPlus from "element-plus";
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/display.css'

import { GlobalCmComponent } from "codemirror-editor-vue3";
import { useLoginStore } from "./stores/store";

const app = createApp(App);
app.use(createPinia());
app.use(GlobalCmComponent);
app.use(ElementPlus);
app.use(router);

const store = useLoginStore();

router.beforeEach((to, from, next) => {
    //获取登录信息
    let isLogin = store.getIsLogin;

    if (isLogin) {     //已登录       
        if (!to.meta.isLogin) {
            next({
                path: '/login_home'
            })
        }else{
            next();
        }
    } else {    //未登录
        if (to.meta.isLogin) {
            next({
                path: '/login',
            })
        } else {
            next()
        }
    }
});

app.mount('#app')

表单验证

<!--注册界面-->
<template>
  <div class="login-wrap">
    <el-form
      class="login-container"
      :model="registerForm"
      :rules="registerRules"
      label-position="right"
      label-width="80px"
    >
      <h1 class="title">注册</h1>
      <el-form-item label="用户名称" prop="username">
        <el-input type="text" placeholder="请输入名称" v-model="registerForm.username"></el-input>
      </el-form-item>
      <el-form-item label="用户邮箱" prop="useremail">
        <el-input type="email" placeholder="请输入邮箱" v-model="registerForm.useremail" size="default"></el-input>
      </el-form-item>
      <el-form-item label="用户密码" prop="pass">
        <el-tooltip content="<span>长度为8~15位,必须同时包含大小写字母及数字</span>" raw-content>
          <el-input v-model="registerForm.pass" type="password" placeholder="请输入密码" show-password />
        </el-tooltip>
      </el-form-item>
      <el-form-item label="确认密码" prop="checkPass">
        <el-input
          v-model="registerForm.checkPass"
          type="password"
          placeholder="请再次输入密码"
          show-password
        />
      </el-form-item>
      <el-form-item label="验证码" prop="checkCode">
        <el-input v-model="registerForm.checkCode" placeholder="请输入验证码" />
      </el-form-item>
      <el-form-item label-width="100px">
        <CharacterVerification ref="ver"></CharacterVerification>
      </el-form-item>
      <el-form-item label-width="0px">
        <el-button type="primary" @click="registerUser()" style="width: 48%;">用户注册</el-button>
        <el-button style="width: 48%;" @click="gotoLogin()">返回登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts">
import { useRouter } from "vue-router";
import { ref, defineComponent, reactive } from 'vue';
import CharacterVerification from '../components/CharacterVerification.vue';

export default defineComponent({
  components: { CharacterVerification },
  setup() {
    const router = useRouter();
    //表单内容
    const registerForm = reactive({
      username: '',
      useremail: '',
      pass: '',
      checkPass: '',
      checkCode: ''
    })
    const ver = ref();

    // 自定义验证规则
    const validatePass = (rule: any, value: any, callback: any) => {
      const reg = /^(?=.*\d)(?=.*[a-zA-Z])[\da-zA-Z]{8,15}$/;
      if (registerForm.checkPass != null && registerForm.checkPass !== '') {
        if (value != registerForm.checkPass) {
          callback(new Error('输入密码不一致'));
        }
      }
      if (!reg.test(value)) {
        callback(new Error('长度为8~15位,必须同时包含大小写字母及数字'));
      }
      callback();

    }
    const validateCheckPass = (rule: any, value: any, callback: any) => {
      const reg = /^(?=.*\d)(?=.*[a-zA-Z])[\da-zA-Z]{8,15}$/;
      if (value !== registerForm.pass) {
        callback(new Error('两次密码输入不一致'));
      }
      if (!reg.test(value)) {
        callback(new Error('长度为8~15位,必须同时包含大小写字母及数字'));
      }
      callback();

    }

    //检查验证码是否正确
    const validateVerificationCode = (rule: any, value: any, callback: any) => {
      if (!ver.value.validate(value)) {
        callback(new Error('验证码错误'));
      } else {
        callback()
      }
    }
    // 定义校验规则
    const registerRules = reactive({
      username: [
        { required: true, message: '用户名称不能为空', trigger: 'blur' },
        { min: 2, max: 32, message: '名称长度只能在2~32之间', trigger: 'blur' }
      ],
      useremail: [
        { required: true, message: '邮箱不能为空', trigger: 'blur' },
        { type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
      ],
      pass: [
        { required: true, message: '密码不能为空', trigger: 'blur' },
        { min: 8, max: 15, message: '密码位数只能在8~15之间', trigger: 'blur' },
        { validator: validatePass, trigger: 'blur' }
      ],
      checkPass: [
        { required: true, message: '密码不能为空', trigger: 'blur' },
        { min: 8, max: 15, message: '密码位数只能在8~15之间', trigger: 'blur' },
        { validator: validateCheckPass, trigger: 'blur' }
      ],
      checkCode: [
        { required: true, message: '验证码不能为空', trigger: 'blur' },
        { validator: validateVerificationCode, trigger: 'blur' }
      ]
    })

    function registerUser() {
      router.push({ path: "/login" });
    }
    function gotoLogin() {
      router.push({ path: "/login" });
    }

    return {
      ver,
      registerForm,
      registerRules,
      registerUser,
      gotoLogin,

    }
  }


})
</script>
<style>
.login-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding-top: 10%;
}

.login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}

.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}
</style>

效果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值