项目改造,进入 demo-schedule 项目中,下载 pinia 依赖
在 main.js 中开启 pinia
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/router.js'
import {createPinia} from 'pinia'
let pinia = createPinia()
const app = createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')
开启 pinia 的代码会经常使用,可以单独抽出来成为一个 js 文件
pinia.js:
import {createPinia} from 'pinia'
let pinia = createPinia()
export default pinia
在 main.js 中直接导入即可
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/router.js'
import pinia from './pinia.js'
const app = createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')
userStore.js:
/* 专门用于存储用户状态的pinia */
import {defineStore} from 'pinia'
export const defineUser = defineStore(
'loginUser',
{
state:()=>{
return{
uid:0,
username:'',
}
},
getters:{
},
actions:{
}
}
)
scheduleStore.js :
import {defineStore} from 'pinia'
export const defineSchedule = defineStore(
'scheduleList',
{
state:()=>{
return {
itemList:[
{
sid:1,
uid:1,
title:'学习Java',
completed:0,
}
],
itemList:[
{
sid:1,
uid:1,
title:'学习Java',
completed:0,
}
],
itemList:[
{
sid:1,
uid:1,
title:'学习Java',
completed:0,
}
],
}
}
}
)
Header.vue:
在 Header 中导入 pinia,增加 v-if 判断,如果已经登录,则显示退出登录和查看日程,如果未登录,则显示登录和注册按钮,同时完成 logout 的退出方法:
<script setup>
/* 导入 pinia 数据 */
import {defineUser} from '../store/userStore.js'
import {defineSchedule} from '../store/scheduleStore.js'
import {useRouter} from 'vue-router'
let router = useRouter()
let sysUser = defineUser()
let schedule = defineSchedule()
function logout() {
// 清楚所有 pinia 数据
sysUser.$reset()
schedule.$reset()
// 跳转到登录页面
router.push("/login")
}
</script>
<template>
<div>
<h1 class = 'ht'>欢迎使用日程管理系统</h1>
<div>
<div class = 'optionDiv' v-if="sysUser.username == ''">
<router-link to = '/login'>
<button class = 'b1s'>登录</button>
</router-link>
<router-link to = '/regist'>
<button class = 'b1s'>注册</button>
</router-link>
</div>
<div class = 'optionDiv' v-else>
欢迎{{sysUser.username}}
<button class = 'b1b' @click = "logout()">退出登录</button>
<router-link to = '/showSchedule'>
<button class = 'b1b'>查看日程</button>
</router-link>
</div>
<br>
</div>
</div>
</template>
<style scoped>
.ht{
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.b1s{
border: 2px solid powderblue;
border-radius: 4px;
width:60px;
background-color: antiquewhite;
}
.b1b{
border: 2px solid powderblue;
border-radius: 4px;
width:100px;
background-color: antiquewhite;
}
.optionDiv{
width: 400px;
float: right;
}
</style>
对后端的 SysUserController 类中的 login 方法,成功登录进行修改
前端 Login.vue 中,登录成功后,接收后端响应回来的用户名 id 和用户名,存储在 userStore 中
<script setup>
import {ref,reactive} from 'vue'
import {useRouter} from 'vue-router'
const router = useRouter()
import {defineUser} from '../store/userStore.js'
let sysUser = defineUser()
import request from '../utils/request'
//响应式数据,保存用户输入的表单信息
let loginUser = reactive({
username:'',
userPwd:'',
})
// 响应式数据,保存校验的提示信息
let usernameMsg = ref('')
let userPwdMsg = ref('')
//校验用户名的方法
function checkUsername() {
// 定义正则表达式
var usernameReg = /^[a-zA-Z0-9]{5,10}$/
// 校验用户名
if (!usernameReg.test(loginUser.username)) {
// 格式不合法
usernameMsg.value="格式有误"
return false
}
usernameMsg.value="ok"
return true
}
// 校验密码的方法
function checkUserPwd() {
// 定义正则表达式
var userPwdReg = /^[0-9]{6}$/
// 校验密码
if(!userPwdReg.test(loginUser.userPwd)) {
// 格式不合法
userPwdMsg.value='格式有误'
return false
}
userPwdMsg.value='ok'
return true
}
async function login() {
// 检查表单数据格式正确再提交
let flg1 = checkUsername()
let flg2 = checkUserPwd()
if (!(flg1 && flg2)) {
return
}
let {data} = await request.post('user/login', loginUser)
if (data.code == 200) {
alert("登录成功")
// 将后返回的登录的用户信息,更新到 pinia 中
sysUser.uid = data.data.loginUser.uid
sysUser.username = data.data.loginUser.username
// 跳转到 showSchedule
router.push("/showSchedule")
} else if (code == 503) {
alert("密码有误")
} else if (code == 501) {
aletr("用户名有误")
} else {
alert("未知错误")
}
}
</script>
<template>
<div>
<h3 class = 'ht'>请登录</h3>
<table class = 'tab' cellspacing = '0px'>
<tr class = 'ltr'>
<td>请输入账号</td>
<td>
<input class = 'ipt'
type = 'text'
v-model="loginUser.username"
@blur="checkUsername()">
<span id = "usernameMsg" v-text="usernameMsg"></span>
</td>
</tr>
<tr class = 'ltr'>
<td>请输入密码</td>
<td>
<input class = 'ipt'
type = 'password'
v-model="loginUser.userPwd"
@blur="checkUserPwd()">
<span id = "userPwdMsg" v-text="userPwdMsg"></span>
</td>
</tr>
<tr class = 'ltr'>
<td colspan="2" class = 'buttonContainer'>
<input class = 'btn1' type = 'button' @click="login()" value = '登录'>
<input class = 'btn1' type = 'button' value = '重置'>
<router-link to = '/regist'>
<button class = 'btn1'>去注册</button>
</router-link>
</td>
</tr>
</table>
</div>
</template>
<style scoped>
.ht{
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.tab{
width: 500px;
border: 5px solid cadetblue;
margin: 0px auto;
border-radius: 5px;
font-family: 幼圆;
}
.ltr td{
border: 1px solid powderblue;
}
.ipt{
border: 0px;
width: 50%;
}
.btn1{
border: 2px solid powderblue;
border-radius: 4px;
width:60px;
background-color: antiquewhite;
}
#usernameMsg , #userPwdMsg {
color: gold;
}
.buttonContainer{
text-align: center;
}
</style>
接下来,我们还要设置一个路由的全局前置守卫,判断一下是否可以访问 showSchedule
import {createRouter, createWebHashHistory} from 'vue-router'
import Login from '../components/Login.vue'
import Regist from '../components/Regist.vue'
import ShowSchedule from '../components/ShowSchedule.vue'
import pinia from '../pinia.js'
import { defineUser } from '../store/userStore.js'
let sysUser = defineUser(pinia)
let router = createRouter(
{
history:createWebHashHistory(),
routes:[
{
path:'/',
redirect:"/showSchedule"
},
{
path:'/login',
component:Login,
},
{
path:'/regist',
component:Regist,
},
{
path:'/showSchedule',
component:ShowSchedule,
},
]
}
)
// 路由的全局前置守卫, 判断是否可以访问 showSchedule
router.beforeEach((to,from,next) => {
if(to.path == '/showSchedule') {
// 登陆过放行
// 没登陆过,回到登录页
if (sysUser.username == '') {
next('/login')
} else {
next()
}
} else {
next()
}
})
export default router
接下来处理显示所有日程数据的问题,showSchedule.vue 中向后端发送异步请求,查询数据并且将数据在前端页面进行展示
<script setup>
// 导入 pinia 数据
import {defineUser} from '../store/userStore.js'
import {defineSchedule} from '../store/scheduleStore.js'
let sysUser = defineUser()
let schedule = defineSchedule()
import {ref, reactive, onUpdated, onMounted} from 'vue'
import request from '../utils/request'
// 第一次挂载完毕后立即向后端发送请求,获取最新数据
onMounted(async function () {
showSchedule()
})
// 发送异步请求
async function showSchedule() {
let {data} = await request.get("/schedule/findAllSchedule",{params:{'uid':sysUser.uid}})4
console.log(data)
}
</script>
<template>
<div>
<h3 class="ht">您的日程如下</h3>
<table class="tab" cellspacing="0px">
<tr class="ltr">
<th>编号</th>
<th>内容</th>
<th>进度</th>
<th>操作</th>
</tr>
<tr class="ltr" v-for="item,index in schedule.itemList" :key="index">
<td v-text="index+1"></td>
<td>
<input type = "text" v-model="item.title">
</td>
<td>
<input type = "radio" value = "1" v-model="item.completed">已完成
<input type = "radio" value = "0" v-model="item.completed">未完成
</td>
<td class="buttonContainer">
<button class="btn1">删除</button>
<button class="btn1">保存修改</button>
</td>
</tr>
<tr class="ltr buttonContainer">
<td colspan="4">
<button class="btn1">新增日程</button>
</td>
</tr>
</table>
</div>
</template>
<style scoped>
.ht {
text-align: center;
color: cadetblue;
font-family: 幼圆;
}
.tab {
width: 80%;
border: 5px solid cadetblue;
margin: 0px auto;
border-radius: 5px;
font-family: 幼圆;
}
.ltr td {
border: 1px solid powderblue;
}
.ipt {
border: 0px;
width: 50%;
}
.btn1 {
border: 2px solid powderblue;
border-radius: 4px;
width: 100px;
background-color: antiquewhite;
}
#usernameMsg,
#userPwdMsg {
color: gold;
}
.buttonContainer {
text-align: center;
}
</style>
```
后端中的 SysScheduleController 类中进行 findAllSchedule 方法的编写
服务层代码:
Dao 层代码:
再回到前端 showSchedule.vue 中发送异步请求:
接下来完成新增日程功能:
showSchedule.vue 的新增日程 button 上添加函数:
在上面实现 addItem 函数
SysScheduleController 中增加一个 addDefaultSchedule 方法
最终在 SysScheduleDaoImpl 中的 addDefault 中实现:
保存修改功能:
在后端实现功能:
SysScheduleController:
SysScheduleDaoImpl:
再实现删除功能:
完!