案例开发 - 日程管理 - 第七期

发布于:2025-09-11 ⋅ 阅读:(18) ⋅ 点赞:(0)

项目改造,进入 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:

再实现删除功能:

完!


网站公告

今日签到

点亮在社区的每一天
去签到