SpringBoot3+Vue3实战(Vue3快速开发登录注册页面并对接后端接口)(4)

目录

一、SpringBoot3+Vue3实现基本增删改查。前后端通信交互、配置后端跨域请求。数据批量删除。(博客链接)

二、SpringBoot3+Vue3快速开发登录、注册页面并实现对接。

(1)操作数据表employee(员工信息表)。

<1>修改employee表的字段组成。

<2>填补对应数据库数据。

(2)修改Employee实体类。

<1>新增对应成员属性。

<2>新增对应getter、setter方法。

<3>修改之前的toString()方法。

(3)修改mapper层代码。

<1>修改新增SQL。

<2>修改更新SQL。

<3>EmployeeMapper接口代码示例。

(4)员工信息(Employee.vue)页面。

<1>前端代码示例。

<2>员工信息的页面渲染效果。

<3>对话框---新增---某些字段设为必填项。(表单校验)

表单标签(el-form)添加ref。

保存按钮绑定事件函数save中触发校验。

表单标签(el-form)绑定校验规则。(:rules)

针对username设置校验规则。(required、message、trigger)

在对话框的对应需校验表单项添加prop属性。

给名称(name)、工号(no)也绑定校验"必填项"。

关闭对话框销毁旧对话框对象。(属性destroy-on-close)

(5)新建登录页面。(Login.vue)

<1>登录页面基本框架。

配置路由。(不是嵌套子路由)

导航栏---退出登录。(index)

<2>登录页面代码示例。

前端登录页面渲染效果图示。

表单项(username、password)校验。(属性ref、:rules)

表单项对应规则。(属性prop)

表单项校验效果图示。(鼠标未输入、且失焦)

登录绑定login函数。(若校验成功--->post请求后端接口"/login")

(6)后端代码编写。(登录)

<1>controller层登录接口。

<2>service层的登录业务处理。

自定义异常。(CustomerException)

封装返回前端数据结果类。(Result)

全局异常捕获处理器。(GlobalExceptionHandler)

前端处理请求(request)和响应(response)的工具类。

配置前后端跨域配置类。

service层登录逻辑代码示例。

<3>mapper层SQL。

<4>登录页面进行登录操作图示。

<5>获取后端返回的员工对象。(实时渲染右上角用户名称)

存储用户信息。(localStorage.setItem(xxx))

主页面(Manager.vue)获取登录时存储的用户信息。

(7)新建注册页面。(Register.vue)


一、SpringBoot3+Vue3实现基本增删改查。前后端通信交互、配置后端跨域请求。数据批量删除。(博客链接)


  • 注意:关于本篇博客的案例《员工信息的前端页面代码、后端接口(controller)、service、mapper层代码》基本都在上面那篇博客中已实现。需要的可以自取。
  • 这篇博客的主要内容:学习《使用Vue3快速开发登录、注册页面并对接后台》。前端Vue页面与后端SpringBoot服务器进行对接。实现员工登录或注册进入系统的功能。

二、SpringBoot3+Vue3快速开发登录、注册页面并实现对接。

(1)操作数据表employee(员工信息表)。
<1>修改employee表的字段组成。
  • employee表字段原组成。

  • 添加3个字段:用户名(username)、密码(password)、角色(role)。

<2>填补对应数据库数据。
(2)修改Employee实体类。
<1>新增对应成员属性。
java 复制代码
package com.hyl.entity;

public class Employee {
    private Integer id;
    private String username;
    private String password;
    private String role;
    private String name;
    private String sex;
    private String no;
    private Integer age;
    private String description;
    //数据库字段:department_id (下划线命名)
    //实体类属性:departmentId (驼峰命名)
    private Integer departmentId;
}

<2>新增对应getter、setter方法。
java 复制代码
 public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

<3>修改之前的toString()方法。
java 复制代码
//toString方法
    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", role='" + role + '\'' +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", no='" + no + '\'' +
                ", age=" + age +
                ", description='" + description + '\'' +
                ", departmentId=" + departmentId +
                '}';
    }
(3)修改mapper层代码。
<1>修改新增SQL。

XML 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyl.mapper.EmployeeMapper">

    <insert id="insert" parameterType="com.hyl.entity.Employee">
        insert into `employee`(username,password,role,name,sex,no,age,description,department_id)
        values (#{username},#{password},#{role},#{name},#{sex},#{no},#{age},#{description},#{departmentId})
    </insert>

</mapper>

<2>修改更新SQL。

XML 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyl.mapper.EmployeeMapper">

    <update id="updateById" parameterType="com.hyl.entity.Employee">
        update `employee` set username = #{username},password = #{password},role = #{role}, name = #{name},sex=#{sex},no=#{no},age=#{age},
        description=#{description},department_id=#{departmentId}
        where id = #{id}
    </update>
    
</mapper>

<3>EmployeeMapper接口代码示例。
java 复制代码
package com.hyl.mapper;

import com.hyl.entity.Employee;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface EmployeeMapper {

    //通过注解形式完成SQL语句的查询
    //简单SQL可以直接使用注解形式。动态SQL最好使用XML文件形式
    @Select("select * from `employee` where id = #{id}")
    Employee selectById(Integer id);

    List<Employee> selectAll(Employee employee);

    void insert(Employee employee);

    void updateById(Employee employee);

    @Delete("delete from `employee` where id = #{id}")
    void deleteById(Integer id);
}
(4)员工信息(Employee.vue)页面。
<1>前端代码示例。
html 复制代码
 <el-table-column label="用户名" prop="username"/>
html 复制代码
<el-table-column label="角色" prop="role">
            <template #default="scope">
              <span v-if="scope.row.role === 'EMP'">员工</span>
            </template>
</el-table-column>

<2>员工信息的页面渲染效果。
  • 一般员工信息页面只会显示用户名、角色。而密码将不会直接显示。

<3>对话框---新增---某些字段设为必填项。(表单校验)
html 复制代码
<el-form-item label="用户名">
          <el-input v-model="data.form.name" autocomplete="off" placeholder="请输入用户名"/>
</el-form-item>

表单标签(el-form)添加ref。
html 复制代码
<el-form ref="formRef" :model="data.form" label-width="80px" style="padding-right: 50px;padding-top: 20px">
javascript 复制代码
import {reactive,ref} from "vue";

const formRef = ref();

保存按钮绑定事件函数save中触发校验。
javascript 复制代码
//对话框的保存按钮事件
const save = () =>{
  formRef.value.validate((valid)=>{
    //通过校验才能点击更新或新增的保存操作
    if(valid){
      //有id进行更新操作。无id进行新增操作
      data.form.id ? update() : add()
    }
  })
}

表单标签(el-form)绑定校验规则。(:rules)
html 复制代码
<el-form ref="formRef" :rules="data.rules" :model="data.form" label-width="80px" style="padding-right: 50px;padding-top: 20px">
针对username设置校验规则。(required、message、trigger)
  • 设置了required为true表示该字段必填。message是当未满足必填条件时显示的提示信息 "请输入用户名" 。trigger为blur表示在输入框失去焦点时触发验证。
javascript 复制代码
import {reactive,ref} from "vue";

const formRef = ref();

const data = reactive({
  rules:{
    username:[
      { required:true , message: '请输入用户名' , trigger:'blur'}
    ]
  }
})

在对话框的对应需校验表单项添加prop属性。
html 复制代码
<el-form-item label="用户名" prop="username">
          <el-input v-model="data.form.username" autocomplete="off" placeholder="请输入用户名"/>
</el-form-item>

给名称(name)、工号(no)也绑定校验"必填项"。
html 复制代码
<el-form-item label="名称" prop="name">
          <el-input v-model="data.form.name" autocomplete="off" placeholder="请输入名称"/>
</el-form-item>
       
<el-form-item label="工号" prop="no">
          <el-input v-model="data.form.no" autocomplete="off" placeholder="请输入工号"/>
</el-form-item>

javascript 复制代码
import {reactive,ref} from "vue";

const data = reactive({
  rules:{
    username:[
      { required:true , message: '请输入用户名' , trigger:'blur'}
    ],
    name:[
      { required:true , message: '请输入名称' , trigger:'blur'}
    ],
    no:[
      { required:true , message: '请输入工号' , trigger:'blur'}
    ]
  }
})

  • 页面渲染效果。

关闭对话框销毁旧对话框对象。(属性destroy-on-close)
html 复制代码
<el-dialog title="员工信息" v-model="data.formVisible" width="500" destroy-on-close>
      <el-form ref="formRef" :rules="data.rules" :model="data.form" label-width="80px" style="padding-right: 50px;padding-top: 20px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="data.form.username" autocomplete="off" placeholder="请输入用户名"/>
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="data.form.name" autocomplete="off" placeholder="请输入名称"/>
        </el-form-item>
        <el-form-item label="性别">
          <el-radio-group v-model="data.form.sex">
            <el-radio value="男">男</el-radio>
            <el-radio value="女">女</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="工号" prop="no">
          <el-input v-model="data.form.no" autocomplete="off" placeholder="请输入工号"/>
        </el-form-item>
        <!--   设置最小年龄18  最大年龄100   -->
        <el-form-item label="年龄">
          <el-input-number v-model="data.form.age" :min="18" :max="100" style="width: 250px" autocomplete="off" placeholder="年龄>=18与年龄<=100"/>
        </el-form-item>
        <!--  设置类型:文本域  :rows设置默认显示三行  -->
        <el-form-item label="个人简介">
          <el-input type="textarea" :rows="3" v-model="data.form.description" autocomplete="off" placeholder="请输入个人简介"/>
        </el-form-item>

      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="data.formVisible = false">取消</el-button>
          <el-button type="primary" @click="save">
            保存
          </el-button>
        </div>
      </template>
</el-dialog>

  • 这样点击"取消"关闭某次对话框时,下次新对话框就不会存留着上次的校验失败提示。
(5)新建登录页面。(Login.vue)
<1>登录页面基本框架。

配置路由。(不是嵌套子路由)

导航栏---退出登录。(index)

<2>登录页面代码示例。
html 复制代码
<template>
  <div>
    <div class="login-container">
<!--   登录表单容器   -->
      <div class="login-box">

        <div style="padding: 40px 30px;background-color: #fbfcf8;margin-left: 200px;border-radius: 5px">
          <div style="margin-bottom: 30px;font-weight: bold;font-size: 24px;color: #514343;text-align: center" >
            欢迎登录hyl信息管理系统
          </div>

          <el-form ref="formRef" :model="data.form" style="width: 350px">
            <el-form-item>
              <el-input v-model="data.form.username" placeholder="请输入用户名" prefix-icon="User"></el-input>
            </el-form-item>
            <el-form-item>
              <el-input v-model="data.form.password" placeholder="请输入密码" prefix-icon="Lock" show-password></el-input>
            </el-form-item>
            <div style="margin-top: 20px;margin-bottom: 20px">
              <el-button size="large" style="width: 100%;" type="primary">登 录</el-button>
            </div>
            <div style="margin-bottom: 20px">
              <el-button size="large" style="width: 100%;" type="primary">注 册</el-button>
            </div>
            <!--  可以使用text-decoration:none 让链接不显示下划线  -->
            <div style="text-align: right">没有账号?请 <a style="color: #1967e3;" href="/register">注册</a></div>
          </el-form>
        </div>

      </div>
    </div>


  </div>
</template>

<script setup>

import {reactive} from "vue";

const data = reactive({
  form:{},
})

</script>

<style scoped>
.login-container {
  /*占满可视高度*/
  height: 100vh;
  /*隐藏超出高度*/
  overflow: hidden;
  /*背景图*/
  background-image: url("@/assets/bimage2.jpeg");
  /*背景图片大小*/
  background-size: cover;
  /*设置背景图移动*/
  background-position: -450px -120px;
}

.login-box {
  /*绝对定位*/
  position: absolute;
  width: 50%;
  height: 100vh;
  /*靠右*/
  right: 0;
  /*flex布局*/
  display: flex;
  align-items: center;
  background-color: #f1ebe2;
}

</style>
前端登录页面渲染效果图示。

表单项(username、password)校验。(属性ref、:rules)
html 复制代码
<el-form ref="formRef" :rules="data.rules" :model="data.form" style="width: 350px">
javascript 复制代码
import {reactive,ref} from "vue";

const formRef = ref()

const data = reactive({
  form:{},
  rules:{
    username :[
      { required: true ,message:'请输入用户名',trigger:'blur'}
    ],
    password :[
      { required: true ,message:'请输入密码',trigger:'blur'}
    ],
  },
})

表单项对应规则。(属性prop)
html 复制代码
<el-form-item prop="username">
              <el-input v-model="data.form.username" placeholder="请输入用户名" prefix-icon="User"></el-input>
</el-form-item>
           
<el-form-item prop="password">
              <el-input v-model="data.form.password" placeholder="请输入密码" prefix-icon="Lock" show-password></el-input>
</el-form-item>

表单项校验效果图示。(鼠标未输入、且失焦)

登录绑定login函数。(若校验成功--->post请求后端接口"/login")
html 复制代码
<div style="margin-top: 20px;margin-bottom: 20px">
     <el-button size="large" style="width: 100%;" type="primary" @click="login">登 录</el-button>
</div>
javascript 复制代码
import {reactive,ref} from "vue";
import request from "@/utils/request.js";
import {ElMessage} from "element-plus";

const formRef = ref()

//登录按钮操作方法
const login = () =>{
  //开始校验
  formRef.value.validate((valid)=>{
    if(valid){
      //表单项(字段)验证通过
      request.post("/login",data.form).then(res=>{
        if(res.code === '200'){  //登录成功
          ElMessage.success('登录成功')
          //登录成功后,跳转主页。等500ms进行跳转
          setTimeout(()=>{
            location.href = '/manager/home'
          },500)
        }else {  //登录失败
          ElMessage.error(res.msg)
        }
      })
    }
  })
}
(6)后端代码编写。(登录)
<1>controller层登录接口。
java 复制代码
package com.hyl.controller;

import com.hyl.common.Result;
import com.hyl.entity.Employee;

import com.hyl.service.EmployeeService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

//表示对外提供可访问接口的类
@RestController
public class WebController {

    @Resource
    private EmployeeService employeeService;
    
    //测试接口(不必理会)
    @GetMapping("/hello")
    public Result hello(){
        return Result.success("hello");
    }

    //登录接口
    //返回登录成功后的员工对象通过@RestController响应成JSON对象给前端
    //前端(res.data)再将JSON对象转换成JSON字符串临时存储用户信息
    @PostMapping("/login")
    public Result login(@RequestBody Employee employee){
        Employee dbEmployee = employeeService.login(employee);
        return Result.success(dbEmployee);
    }
    
}

<2>service层的登录业务处理。
自定义异常。(CustomerException)
java 复制代码
package com.hyl.exception;

public class CustomerException extends RuntimeException{
    private String code;
    private String msg;

    public CustomerException(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    //getter|setter方法
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

封装返回前端数据结果类。(Result)
java 复制代码
package com.hyl.common;

/**
 * 统一后端返回的数据结果类型
 */
public class Result {
    //请求状态码
    private String code;
    //成功或错误信息
    private String msg;
    //返回数据结果
    private Object data;

    //常用静态方法

    //请求成功且无数据返回
    public static Result success(){
        Result result = new Result();
        result.setCode("200");
        result.setMsg("请求成功");
        return result;
    }

    //请求成功且有数据返回。
    public static Result success(Object data) {
        //直接调用静态方法设置状态码、请求成功信息
        Result result = Result.success();
        result.setData(data);
        return result;
    }

    //请求失败且无数据返回
    public static Result error(){
        Result result = new Result();
        result.setCode("500");
        result.setMsg("系统出错了!");
        return result;
    }

    //请求失败且无数据返回。适配自定义异常(传递code、msg)
    public static Result error(String code,String msg){
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    //getter、setter方法
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

全局异常捕获处理器。(GlobalExceptionHandler)
java 复制代码
package com.hyl.exception;

import com.hyl.common.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

//标识全局异常处理器并设置捕获路径
//因为异常产生最终都会归宿到controller中,所有异常统一在controller包中接口中处理。
@ControllerAdvice("com.hyl.controller")
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) //捕获所有系统异常
    @ResponseBody//返回json串
    public Result error(Exception e) {
        //更清晰看到后端控制台报的错误
        e.printStackTrace();
        //返回Result的error()方法设置的错误信息(code、msg)给前端
        return Result.error();
    }

    @ExceptionHandler(CustomerException.class) //捕获自定义异常
    @ResponseBody//返回json串
    public Result error(CustomerException e) {  //自定义异常的参数code、msg
        //更清晰看到后端控制台报的错误
        e.printStackTrace();
        //Result的error(String code,String Msg)方法设置获取到的错误信息(code、msg)
        return Result.error(e.getCode(),e.getMsg());
    }

}

前端处理请求(request)和响应(response)的工具类。
javascript 复制代码
import { ElMessage } from 'element-plus'
import axios from "axios";

const request = axios.create({
    //设置后台请求地址
    baseURL: 'http://localhost:9090',
    timeout: 30000  // 后台接口超时时间设置
})

// request 拦截器(数据请求)
// 可以自请求发送前对请求做一些处理
request.interceptors.request.use(config => {
    //设置统一的数据传输格式json、数据传输编码utf-8
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        //响应对象response中提取实际数据部分,存储在变量res中
        let res = response.data;
        // 兼容服务端返回的字符串数据
        //如果res是字符串且不为空字符串,则使用JSON.parse方法将其解析为JavaScript对象;
        //如果 res 为空字符串,则保持原样。
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
       if(error.response.status === 404){
           //404 状态码表示请求的资源未找到,通常意味着请求的接口不存在
           ElMessage.error('未找到请求接口')
       }else if(error.response.status === 500){
           //500:之前后端设置的全局系统异常处理捕获
           //500 状态码表示服务器内部错误,通常是由于后端代码出现异常
           ElMessage.error('系统异常,请查看后端控制台报错')
       }else{
           //其它情况统一打印错误信息
           console.error(error.message)
       }
       //将错误继续抛出,以便后续的代码可以继续处理该错误
       return Promise.reject(error)

    }
)

export default request

配置前后端跨域配置类。
java 复制代码
package com.hyl.common;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * 跨域配置类。用于解决前端和后端由于不同源(协议、域名、端口不同)导致的跨域请求问题
 * @Configuration 让该配置类注入到Spring容器中并能够扫描到其下类下注解
 */
@Configuration
public class CorsConfig {

    /**
     * 创建并注册CorsFilter bean,用于处理跨域请求
     * @return CorsFilter实例,Spring会在请求处理过程中使用该过滤器处理跨域请求
     * @Bean 注解会让该方法的返回值注入到Spring容器中
     */
    @Bean
    public CorsFilter corsFilter() {
        // 创建一个基于URL的跨域配置源对象,用于存储和管理不同URL路径的跨域配置
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 创建一个跨域配置对象,用于设置具体的跨域规则
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 设置允许访问的源地址,这里使用通配符"*",表示允许所有源地址访问
        corsConfiguration.addAllowedOrigin("*");
        // 设置允许的请求头,"*"表示允许所有请求头,即前端可以在请求中携带任意请求头
        corsConfiguration.addAllowedHeader("*");
        // 设置允许的请求方法,"*"表示允许所有的HTTP请求方法,如GET、POST、PUT、DELETE等
        corsConfiguration.addAllowedMethod("*");
        // 将跨域配置应用到所有的接口路径上,"/**"表示匹配所有路径
        source.registerCorsConfiguration("/**", corsConfiguration);
        // 创建并返回CorsFilter实例,传入配置源对象,Spring会使用该过滤器处理跨域请求
        return new CorsFilter(source);
    }
}

service层登录逻辑代码示例。
java 复制代码
public Employee login(Employee employee){
        //用户名
        String username = employee.getUsername();
        //先查询数据库中是否有该用户名
        Employee dbEmployee = employeeMapper.selectByUserName(username);
        if(Objects.isNull(dbEmployee)){ //未查询到用户
            //返回自定义异常。交给全局异常捕获器处理
            //将错误状态码返回前端,前端捕获返回的res.code。提示登录失败与错误信息:用户不存在
            throw new CustomerException("500","用户不存在");
        }
        //用户存在
        //判断密码是否正确
        String password = employee.getPassword();
        if(!dbEmployee.getPassword().equals(password)){
            //用户输入的密码与数据库的密码不匹配
            //返回自定义异常。交给全局异常捕获器处理
            //将错误状态码返回前端,前端捕获返回的res.code。提示登录失败与错误信息:账号或密码错误
            throw new CustomerException("500","账号或密码错误");
        }
        //所有逻辑判断没有问题,返回数据库的Employee对象
        return dbEmployee;
    }

<3>mapper层SQL。
java 复制代码
@Select("select * from `employee` where username = #{username}")
    Employee selectByUserName(String username);

<4>登录页面进行登录操作图示。




<5>获取后端返回的员工对象。(实时渲染右上角用户名称)
存储用户信息。(localStorage.setItem(xxx))
javascript 复制代码
//登录按钮操作方法
const login = () =>{
  //开始校验
  formRef.value.validate((valid)=>{
    if(valid){
      //表单项(字段)验证通过
      request.post("/login",data.form).then(res=>{
        if(res.code === '200'){  //登录成功
          ElMessage.success('登录成功')
          //登录成功后,跳转主页。等500ms进行跳转
          setTimeout(()=>{
            location.href = '/manager/home'
          },500)
          //存储后台返回的员工对象信息
          //把后端传来的JSON对象转换成JSON字符串存储
          localStorage.setItem('xm-pro-user',JSON.stringify(res.data))
        }else {  //登录失败
          ElMessage.error(res.msg)
        }
      })
    }
  })
}

主页面(Manager.vue)获取登录时存储的用户信息。
javascript 复制代码
import {reactive} from "vue";

const data = reactive({
  //记得将拿到的JSON字符串转换成JSON对象。这样才能获取到员工名称:data.user.name
  user: JSON.parse(localStorage.getItem('xm-pro-user'))
})


html 复制代码
<!--  右半部分-头像  -->
    <div style="width: 150px;display: flex;align-items: center">
      <img src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" alt="" style="width: 40px;height: 40px">
      <span style="margin-left: 5px;color: white">{{data.user.name}}</span>
    </div>


(7)新建注册页面。(Register.vue)
  • 后面补充。!!!!
相关推荐
vx_bisheyuange1 分钟前
基于SpringBoot的便利店信息管理系统
前端·javascript·vue.js·毕业设计
晚烛2 分钟前
智启工厂脉搏:基于 OpenHarmony + Flutter 的信创工业边缘智能平台构建实践
前端·javascript·flutter
Zsnoin能4 分钟前
都快2026了,还有人不会国际化和暗黑主题适配吗,一篇文章彻底解决
前端·javascript
两个西柚呀6 分钟前
es6和commonjs模块化规范的深入理解
前端·javascript·es6
www_stdio6 分钟前
爬楼梯?不,你在攀登算法的珠穆朗玛峰!
前端·javascript·面试
爱吃大芒果7 分钟前
Flutter 表单开发实战:表单验证、输入格式化与提交处理
开发语言·javascript·flutter·华为·harmonyos
向下的大树25 分钟前
Vue 2迁移Vue 3实战:从痛点到突破
前端·javascript·vue.js
那我掉的头发算什么29 分钟前
【javaEE】UDP与TCP核心原理深度解析:从“不可靠”到“稳如老狗”的进化之路
网络协议·tcp/ip·udp·java-ee·传输层协议
玉米Yvmi33 分钟前
从零理解 CSS 弹性布局:轻松掌控页面元素排布
前端·javascript·css
西洼工作室33 分钟前
前端js汉字手写练习系统
前端·javascript·css