【SpringBoot3+Vue3】五【完】【实战篇】-前端(配合后端)

目录

一、环境准备

1、创建Vue工程

2、安装依赖 

2.1 安装项目所需要的vue依赖 

2.2 安装element-plus依赖

2.2.1 安装

2.2.2 项目导入element-plus

2.3 安装axios依赖

2.4 安装sass依赖

3、目录调整

3.1 删除部分默认目录下文件

3.1.1 src/components下自动生成的内容(删除文件夹下全部内容)

3.1.2 src/assets 下自动生成的内容(删除文件夹下全部内容) 

3.2 api、utils、views目录处理

3.2.1 src下新建目录api、utils、views

 3.2.2 utils下新增request.js文件

3.3 将资料中的静态资源拷贝到assets目录下

3.4 修改app.vue生成的内容

4、启动项目验证

二、注册功能

1、页面搭建 

1.1 views下新建Login.vue

1.2 App.vue导入Login.vue

1.3 查看结果

2、为注册页面绑定数据与事件

2.1 定义数据模型Login.vue

 2.2 注册页面Login.vue表单校验

2.3 验证

3、注册页面后台接口调用 

3.1 启动后端服务

3.2 api目录下新建user.js文件

3.3 Login.vue页面完成调用

4、跨域问题解决

4.1 request.js

4.2 vite.config.js

5、测试验证

三、登录功能

1、登录Login.vue绑定数据 

2、 登录Login.vue数据校验

3、登录页面后端接口调用

3.1 user.js提供登录调用接口

3.2 Login.vue调用后端接口

4、测试验证

5、优化登录表单与注册表单数据显示问题(Login.vue)

四、优化axios响应拦截器与alert

1、axios响应拦截器

2.1 request.js 

2.2 优化Login.vue

2、使用element-plus优化alert

2.1 request.js引用ElMessage 组件处理

2.2  Login.vue引用ElMessage 组件处理

五、主页面布局 

1、Layout页面

1.1 views下新增Layout.vue

 1.2 App.vue导入Layout.vue

2、路由

 2.1 安装vue-router

2.2 创建路由器index.js

2.3 在main.js使用vue-router

2.4 App.vue中声明router-view标签

2.5  Login.vue优化登录成功跳转

2.6 测试验证

3、子路由

3.1 views下创建vue文件 

3.1.1 ArticleCategory.vue

3.1.2 ArticleManage.vue

3.1.3 UserAvatar.vue

3.1.4 UserInfo.vue

3.1.5 UserResetPassword.vue

3.2 index.js

3.3 Layout.vue声明router-view标签

3.4 测试验证

六、文章分类 

1、列表查询

1.1 article.js

1.2 ArticleCategory.vue

2、Pinia状态管理库

2.1 安装pinia

2.2 main.js导入pinia

2.3 定义store

2.4 使用Store

2.5 测试验证

 3、 使用axios请求拦截器解决token繁琐问题

​编辑 3.1 request.js添加请求拦截器

3.2 article.js移除之前添加的请求头

4、pinia-persistedstate-plugin持久化插件

4.1 安装

4.2 pinia中使用persist插件

4.3 在创建定义状态是配置持久化

5、未登录统一处理

6、添加文章分类

6.1  ArticleCategory.vue

6.2 在article.js中提供添加分类的函数

6.3 测试验证

7、修改文章分类 

7.1 修改分类弹窗页面

7.1.1 弹窗标题显示  ArticleCategory.vue

7.1.2 在弹窗上绑定标题 ArticleCategory.vue

7.1.3 为添加分类按钮绑定事件 ArticleCategory.vue

7.1.4 为修改分类按钮绑定事件 ArticleCategory.vue

7.2 修改数据回显 ArticleCategory.vue

7.3 修改文章分类接口调用

7.3.1 article.js中提供修改分类的函数

7.3.2 修改确定按钮的绑定事件 ArticleCategory.vue

7.3.3 调用接口完成修改的函数  ArticleCategory.vue

7.3.4 优化添加时数据回显

8、删除文章分类

 8.1 删除接口

8.2 删除确认框

 8.3 为删除按钮绑定事件

8.4 调用删除接口

8.5 测试验证

七、文章列表 

1、 文章列表查询

 1.1 文章列表页面组件ArticleManage.vue

1.2 解决分页控件英文显示问题main.js

1.3 文章分类数据回显ArticleMange.vue  

1.4 文章列表接口调用

1.4.1 article.js中提供获取文章列表数据的函数

1.4.2 ArticleManage.vue中,调用接口获取数据

1.4.3 当分页条的当前页和每页条数发生变化,重新发送请求获取数据

2 、搜索和重置

3、添加文章

3.1 添加文章抽屉组件

3.2 为添加文章按钮添加单击事件,展示抽屉

3.3 富文本编辑器

3.3.1 安装:

3.3.2 导入组件和样式:

3.3.3 页面使用quill组件:​

3.3.4 样式美化:

3.4 文章封面图片上传

3.5 添加文章接口调用

3.5.1 article.js中提供添加文章函数

3.5.2 为已发布和草稿按钮绑定事件

3.5.3 ArticleManage.vue中提供addArticle函数完成添加文章接口的调用

4、编辑文章

4.1 修改文章抽屉页面

4.1.1 抽屉标题显示 定义标题

4.1.2 在抽屉上绑定标题

4.1.3 为添加文章按钮绑定事件

4.1.4 为修改文章按钮绑定事件

4.2 数据回显

4.2.1 通过插槽的方式得到被点击按钮所在行的数据

4.2.2 回显函数

4.3 修改文章接口调用

4.3.1 article.js中提供修改文章的函数

4.3.2 修改发布与草稿按钮的绑定事件

4.3.3 调用接口完成修改的函数

5、删除文章

5.1 接口调用

5.2 为删除按钮绑定事件

5.3 添加删除弹窗,当用户点击确认后,调用接口删除分类

八、顶部导航栏信息展示

1、 user.js中提供获取个人信息的函数

2、 src/stores/userInfo.js中,定义个人中心状态

3、 Layout.vue中获取个人信息,并存储到pinia中

4、Layout.vue的顶部导航栏中,展示昵称和头像

九 、页面右上角下拉菜单el-dropdown中功能实现

1、路由实现:

2、 退出登录实现:

十、基本资料修改

1、 基本资料页面组件UserInfo.vue

2、 表单数据回显

3、 接口调用

十一、修改头像

1、 修改头像页面组件UserAvatar.vue

2、 头像回显

3、 头像上传

4、 上传头像接口调用

十二、 重置密码

1、user.js 重置密码

 2、UserResetPassword.vue


前言:本项目的终结篇,是一名vue3完成本次课程的前端页面。

一、环境准备

1、创建Vue工程

npm init vue@latest

# 项目名称spring3vue3project

2、安装依赖 

进入到创建项目目录

2.1 安装项目所需要的vue依赖 

# 项目所需要的vue依赖
npm install

2.2 安装element-plus依赖

2.2.1 安装
# 安装element-plus依赖
npm install element-plus --save

2.2.2 项目导入element-plus

打开项目 

code .

修改src/main.js 

import './assets/main.scss'

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'


import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)

app.mount('#app')

2.3 安装axios依赖

npm install axios

2.4 安装sass依赖

# 安装sass依赖 好像是关于css的
npm install sass -D

3、目录调整

直接进到项目文件夹下操作

3.1 删除部分默认目录下文件

3.1.1 src/components下自动生成的内容(删除文件夹下全部内容)

3.1.2 src/assets 下自动生成的内容(删除文件夹下全部内容) 

3.2 api、utils、views目录处理

3.2.1 src下新建目录api、utils、views

 3.2.2 utils下新增request.js文件
// 定制请求实例

//导入axios
import axios from 'axios'; 

//定义一个变量,记录公共的前缀baseURL
const baseURL = 'http://localhost:8080'
const instance = axios.create({baseURL})

// 添加响应拦截器
instance.interceptors.response.use(
    result=>{
        return result.data;

    },
    err=>{
        alert('服务异常')
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

3.3 将资料中的静态资源拷贝到assets目录下

如需,关注,发私信

3.4 修改app.vue生成的内容

删除app.vue中自动生成的内容

<script setup>

</script>

<template>
春天的菠菜

</template>


<style scoped>

</style>

4、启动项目验证

npm run dev

二、注册功能

 

1、页面搭建 

1.1 views下新建Login.vue

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)
</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister">
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码"></el-input>
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else>
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

1.2 App.vue导入Login.vue

<script setup>
import LoginVue from '@/views/Login.vue'

</script>

<template>
<LoginVue/>
</template>


<style scoped>

</style>

1.3 查看结果

2、为注册页面绑定数据与事件

2.1 定义数据模型Login.vue

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})


</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData">
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else>
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

 2.2 注册页面Login.vue表单校验

表单校验可看官网

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}



</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 2.1  :model="registerData"表单声明属性 --> <!-- 2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!-- 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!-- 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else>
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

2.3 验证

3、注册页面后台接口调用 

3.1 启动后端服务

启动前面章节后端服务以及redis 

3.2 api目录下新建user.js文件

//导入request.js请求工具
import request from '@/utils/request.js'

// 提供调用注册接口的函数
export const userRegisterService = (registerData) =>{
    //借助于URLSearchParam完成参数传递
    const params = new URLSearchParams();
    for(let key in registerData){
        params.append(key,registerData[key]);
    }
    return request.post('/user/register',params);
    
}

3.3 Login.vue页面完成调用

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
// 3.3 导入注册的接口
import { userRegisterService} from '@/api/user.js'

//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

//3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    }
}

</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 2.1  :model="registerData"表单声明属性 --> <!-- 2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!-- 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!-- 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else>
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

验证,存在跨域问题

4、跨域问题解决

4.1 request.js

// 定制请求实例

//导入axios  npm install axios
import axios from 'axios';

//定义一个变量,记录公共的前缀baseURL
// const baseURL = 'http://localhost:8080'  
const baseURL = '/api'          // 注释上面代码,解决跨域问题
const instance = axios.create({baseURL})

// 添加响应拦截器
instance.interceptors.response.use(
    result=>{
        return result.data;

    },
    err=>{
        alert('服务异常')
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

4.2 vite.config.js

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
  ,
  // server 部分都是为了解决跨域问题
  server:{
    proxy:{
      '/api':{//获取路径中包含了/api的请求
          target:'http://localhost:8080',//后台服务所在的源
          changeOrigin:true,//修改源
          rewrite:(path)=>path.replace(/^\/api/,'')///api替换为''
      }
    }
  }
})

5、测试验证

三、登录功能

 

1、登录Login.vue绑定数据 

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//二 注册 3.3 导入注册的接口
import { userRegisterService} from '@/api/user.js'

//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//二 注册 2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//二 注册  2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//二 注册  2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

// 二 注册  3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    }
}

// 三 登录 1 绑定数据 复用注册表单的数据模型

</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 二 注册2.1  :model="registerData"表单声明属性 --> <!-- 二 注册2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!--二 注册 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!--二 注册 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 二 注册2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 二 注册2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 二 注册2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 二 注册3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else model="registerDate">  <!-- 三 登录 3.1  :model="registerData"表单声明属性,复用注册 -->
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item>
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input> <!--三 登录 3.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item>
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input> <!--三 登录 3.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>                
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

2、 登录Login.vue数据校验

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//二 注册 3.3 导入注册的接口
import { userRegisterService} from '@/api/user.js'

//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//二 注册 2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//二 注册  2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//二 注册  2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

// 二 注册  3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    }
}

// 三 登录 1 绑定数据 复用注册表单的数据模型
// 三 登录 2  数据校验 复用注册表单的数据校验

</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 二 注册2.1  :model="registerData"表单声明属性 --> <!-- 二 注册2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!--二 注册 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!--二 注册 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 二 注册2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 二 注册2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 二 注册2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 二 注册3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else model="registerDate" rules="rules">  <!-- 三 登录 3.1  :model="registerData"表单声明属性,复用注册 --> <!-- 三 登录 3.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input> <!--三 登录 3.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input> <!--三 登录 3.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>               
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space>登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

3、登录页面后端接口调用

3.1 user.js提供登录调用接口

//导入request.js请求工具
import request from '@/utils/request.js'

// 二  注册函数  提供调用注册接口的函数
export const userRegisterService = (registerData) =>{
    //借助于URLSearchParam完成参数传递
    const params = new URLSearchParams();
    for(let key in registerData){
        params.append(key,registerData[key]);
    }
    return request.post('/user/register',params);
    
}

// 三  登录函数 提供调用登录接口的函数
export const userLoginService = (loginData)=>{
    //借助于URLSearchParam完成参数传递
    const params = new URLSearchParams();
    for(let key in loginData){
        params.append(key,loginData[key]);
    }
    return request.post('/user/login',params);

}

3.2 Login.vue调用后端接口

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//二 注册 3.3 导入注册的接口 //三 登录 3.3 导入登录的接口
import { userRegisterService,userLoginService} from '@/api/user.js'



//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//二 注册 2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//二 注册  2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//二 注册  2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

// 二 注册  3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    }
}

// 三 登录 1 绑定数据 复用注册表单的数据模型
// 三 登录 2  数据校验 复用注册表单的数据校验
// 三 登录 3  登录函数
const login  = async()=>{ 
    //调用接口完成登录
    let result = await userLoginService(registerData.value);
    if(result.code ===1){
        //登录成功
        alert(result.msg?result.msg : '登录成功')

    }else{
        // 登录失败
        alert('登录失败')

    }

}


</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 二 注册2.1  :model="registerData"表单声明属性 --> <!-- 二 注册2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!--二 注册 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!--二 注册 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 二 注册2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 二 注册2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 二 注册2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 二 注册3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false">
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else model="registerDate" rules="rules">  <!-- 三 登录 3.1  :model="registerData"表单声明属性,复用注册 --> <!-- 三 登录 3.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input> <!--三 登录 3.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input> <!--三 登录 3.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>                
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true">
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

4、测试验证

 

5、优化登录表单与注册表单数据显示问题(Login.vue)

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//二 注册 3.3 导入注册的接口 //三 登录 3.3 导入登录的接口
import { userRegisterService,userLoginService} from '@/api/user.js'



//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//二 注册 2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//二 注册  2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//二 注册  2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

// 二 注册  3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    }
}

// 三 登录 1 绑定数据 复用注册表单的数据模型
// 三 登录 2  数据校验 复用注册表单的数据校验
// 三 登录 3  登录函数
const login  = async()=>{ 
    //调用接口完成登录
    let result = await userLoginService(registerData.value);
    if(result.code ===1){
        //登录成功
        alert(result.msg?result.msg : '登录成功')

    }else{
        // 登录失败
        alert('登录失败')

    }

}
// 三 登录 4 定义函数清空数据模型数据(将数据清空)
const clearRegisterDate = ()=>{
    registerData.value={
        username:'',
        password:'',
        rePassword:''
    }

}


</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 二 注册2.1  :model="registerData"表单声明属性 --> <!-- 二 注册2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!--二 注册 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!--二 注册 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 二 注册2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 二 注册2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 二 注册2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 二 注册3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false;clearRegisterDate()"> <!--三 登录 4  调用函数clearRegisterDate() 清空数据 -->
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else model="registerDate" rules="rules">  <!-- 三 登录 3.1  :model="registerData"表单声明属性,复用注册 --> <!-- 三 登录 3.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input> <!--三 登录 3.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input> <!--三 登录 3.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>                
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true;clearRegisterDate()">  <!--三 登录 4  调用函数clearRegisterDate() 清空数据 -->
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

四、优化axios响应拦截器与alert

1、axios响应拦截器

2.1 request.js 

(上图右侧的文件名错误)

// 定制请求实例

//导入axios  npm install axios
import axios from 'axios';

//定义一个变量,记录公共的前缀baseURL
// const baseURL = 'http://localhost:8080'  
const baseURL = '/api'          // 注释上面代码,解决跨域问题
const instance = axios.create({baseURL})

// 添加响应拦截器
instance.interceptors.response.use(
    result=>{
        // 判断业务状态码
        if(result.data.code === 1){
            //成功,正常返回数据
            return result.data;
        }
        // 操作失败
        alert(result.data.msg?result.data.msg : '服务异常')
        // 异步操作的状态转换为失败
        return Promise.reject(result.data)

    },
    err=>{
        alert('服务异常')
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

2.2 优化Login.vue

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//二 注册 3.3 导入注册的接口 //三 登录 3.3 导入登录的接口
import { userRegisterService,userLoginService} from '@/api/user.js'



//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//二 注册 2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//二 注册  2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//二 注册  2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

// 二 注册  3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    /* 使用axios的 request.js 统一处理了,优化这里代码
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    } */
    alert(result.msg?result.msg : '注册成功')
}

// 三 登录 1 绑定数据 复用注册表单的数据模型
// 三 登录 2  数据校验 复用注册表单的数据校验
// 三 登录 3  登录函数
const login  = async()=>{ 
    //调用接口完成登录
    let result = await userLoginService(registerData.value);
      /* 使用axios的 request.js 统一处理了,优化这里代码
    if(result.code ===1){
        //登录成功
        alert(result.msg?result.msg : '登录成功')

    }else{
        // 登录失败
        alert('登录失败')

    }*/
    alert(result.msg?result.msg : '登录成功')

}
// 三 登录 4 定义函数清空数据模型数据(将数据清空)
const clearRegisterDate = ()=>{
    registerData.value={
        username:'',
        password:'',
        rePassword:''
    }

}


</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 二 注册2.1  :model="registerData"表单声明属性 --> <!-- 二 注册2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!--二 注册 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!--二 注册 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 二 注册2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 二 注册2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 二 注册2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 二 注册3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false;clearRegisterDate()"> <!--三 登录 4  调用函数clearRegisterDate() 清空数据 -->
                        ← 返回
                    </el-link>
                </el-form-item>
            </el-form>
            <!-- 登录表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-else model="registerDate" rules="rules">  <!-- 三 登录 3.1  :model="registerData"表单声明属性,复用注册 --> <!-- 三 登录 3.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>登录</h1>
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input> <!--三 登录 3.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="username"> <!--三 登录 3.2  prop="username"绑定校验 -->
                    <el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input> <!--三 登录 3.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>                
                <el-form-item class="flex">
                    <div class="flex">
                        <el-checkbox>记住我</el-checkbox>
                        <el-link type="primary" :underline="false">忘记密码?</el-link>
                    </div>
                </el-form-item>
                <!-- 登录按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = true;clearRegisterDate()">  <!--三 登录 4  调用函数clearRegisterDate() 清空数据 -->
                        注册 →
                    </el-link>
                </el-form-item>
            </el-form>
        </el-col>
    </el-row>
</template>

<style lang="scss" scoped>
/* 样式 */
.login-page {
    height: 100vh;
    background-color: #fff;

    .bg {
        background: url('@/assets/logo2.png') no-repeat 60% center / 240px auto,
            url('@/assets/login_bg.jpg') no-repeat center / cover;
        border-radius: 0 20px 20px 0;
    }

    .form {
        display: flex;
        flex-direction: column;
        justify-content: center;
        user-select: none;

        .title {
            margin: 0 auto;
        }

        .button {
            width: 100%;
        }

        .flex {
            width: 100%;
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

2、使用element-plus优化alert

2.1 request.js引用ElMessage 组件处理

// 定制请求实例

//导入axios  npm install axios
import axios from 'axios';
// 四 4.2 element-plus封装的组件
import { ElMessage } from 'element-plus';

//定义一个变量,记录公共的前缀baseURL
// const baseURL = 'http://localhost:8080'  
const baseURL = '/api'          // 注释上面代码,解决跨域问题
const instance = axios.create({baseURL})

// 添加响应拦截器
instance.interceptors.response.use(
    result=>{
        // 四  4.1 判断业务状态码
        if(result.data.code === 1){
            //成功,正常返回数据
            return result.data;
        }
        // 操作失败
        // alert(result.data.msg?result.data.msg : '服务异常')  
        // 四 4.2 优化alert
        ElMessage.error(result.data.msg?result.data.msg : '服务异常')
        // 异步操作的状态转换为失败
        return Promise.reject(result.data)

    },
    err=>{
        alert('服务异常')
        return Promise.reject(err);//异步的状态转化成失败的状态
    }
)

export default instance;

2.2  Login.vue引用ElMessage 组件处理

<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
//二 注册 3.3 导入注册的接口 //三 登录 3.3 导入登录的接口
import { userRegisterService,userLoginService} from '@/api/user.js'

// 四 4.2 element-plus封装的组件
import { ElMessage } from 'element-plus';

//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)

//二 注册 2.1定义数据模型

const registerData = ref({
    username:'',
    password:'',
    rePassword:''
})

//二 注册  2.2自定义rePassword需要自定义校验规则校验规则的函数,三个参rule 规则,value 值,callback 回调函数
const checkRePassword = (rule,value,callback)=>{
    if(value === '' ){
        callback(new Error('请再次确认密码!'))
    }else if(value !== registerData.value.password){
        callback(new Error('请确保两次密码输入一致性!'))
    }else{
        callback()  //校验通过
    }
}

//二 注册  2.2 定义表单校验规则,rePassword需要自定义校验规则
const rules = {
    username:[
        {required:true,message:'请输入用户名!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    password:[
    {required:true,message:'请输入密码!',trigger:'blur'},
        {min:5,max:16,message:'长度为5-16位非空字符',trigger:'blur'}
    ],
    rePassword:[
        {validator:checkRePassword,trigger:'blur'}
    ]
}

// 二 注册  3.3 调用后台接口,完成注册
const  register = async()=>{
    // registerData 是一个响应式对象,如果要获取值需要.value
    let result = await userRegisterService(registerData.value);
    /* 使用axios的 request.js 统一处理了,优化这里代码
    if(result.code ===1){
        //注册成功
        alert(result.msg?result.msg : '注册成功')

    }else{
        // 注册失败
        alert('注册失败')

    } */
    // 四 4.2 优化alert
    // alert(result.msg?result.msg : '注册成功')
    ElMessage.success(result.msg?result.msg : '注册成功')
}

// 三 登录 1 绑定数据 复用注册表单的数据模型
// 三 登录 2  数据校验 复用注册表单的数据校验
// 三 登录 3  登录函数
const login  = async()=>{ 
    //调用接口完成登录
    let result = await userLoginService(registerData.value);
      /* 使用axios的 request.js 统一处理了,优化这里代码
    if(result.code ===1){
        //登录成功
        alert(result.msg?result.msg : '登录成功')

    }else{
        // 登录失败
        alert('登录失败')

    }*/
    // 四 4.2 优化alert
    // alert(result.msg?result.msg : '登录成功')
    ElMessage.success(result.msg?result.msg : '登录成功')

}
// 三 登录 4 定义函数清空数据模型数据(将数据清空)
const clearRegisterDate = ()=>{
    registerData.value={
        username:'',
        password:'',
        rePassword:''
    }

}


</script>

<template>
    <el-row class="login-page">
        <el-col :span="12" class="bg"></el-col>
        <el-col :span="6" :offset="3" class="form">
            <!-- 注册表单 -->
            <el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">  <!-- 二 注册2.1  :model="registerData"表单声明属性 --> <!-- 二 注册2.2  :rules="rules"绑定校验 -->
                <el-form-item>
                    <h1>注册</h1>
                </el-form-item>
                <el-form-item prop="username">  <!--二 注册 2.2 prop="username"绑定校验 -->
                    <el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>  <!--二 注册 2.1 v-model="registerData.username"绑定属性 -->
                </el-form-item>
                <el-form-item prop="password"> <!-- 二 注册2.2 prop="password"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入密码" v-model="registerData.password"></el-input>  <!-- 二 注册2.1 v-model="registerData.password"绑定属性 -->
                </el-form-item>
                <el-form-item prop="rePassword">  <!-- 2.2 prop="rePassword"绑定校验 -->
                    <el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码" v-model="registerData.rePassword"></el-input>  <!-- 二 注册2.1 v-model="registerData.rePassword"绑定属性 -->
                </el-form-item>
                <!-- 注册按钮 -->
                <el-form-item>
                    <el-button class="button" type="primary" auto-insert-space @click="register"> <!-- 二 注册3.3  @click="register"  绑定注册单击事件 -->
                        注册
                    </el-button>
                </el-form-item>
                <el-form-item class="flex">
                    <el-link type="info" :underline="false" @click="isRegister = false;clearRegisterDate()"> <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天的菠菜

一毛两毛也是动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值