springboot+vue前后端分离项目-项目搭建5
1.改造登录vue/src/views/LoginView.vue,登陆后存储user信息到sessionStorage,进入到login页面移除sessionStorage里的user
2.改造vue/src/components/Header.vue,从sessionStorage中获取user,每个人登陆后根据个人信息显示名称
3.增加vue/src/views/Person.vue,点击个人信息,可带入个人信息后保存
<template>
<div>
<el-card style="width: 150%; margin: 10px">
<el-form ref="form" :model="form" label-width="60px">
<el-form-item label="用户名">
<el-input v-model="form.username" disabled></el-input>
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="form.nickName"></el-input>
</el-form-item>
<el-form-item label="年龄">
<el-input v-model="form.age"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-input v-model="form.sex"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="form.address" type="textarea"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.password"></el-input>
</el-form-item>
</el-form>
<div style="text-align: center">
<el-button type="primary" @click="update">更新保存</el-button>
</div>
</el-card>
</div>
</template>
<script>
import request from "@/utils/request";
export default {
name: "Person",
data() {
return {
form: {}
}
},
created() {
let str = sessionStorage.getItem("user")
this.form = JSON.parse(str)
},
methods: {
update() {
request.put("/user/person", this.form).then(res => {
console.log(res)
if(res.code === '0'){
this.$message({
type: "success",
message: "更新成功"
})
sessionStorage.setItem("user", JSON.stringify(res.data))
}else {
this.$message({
type: "error",
message: "res.msg"
})
}
})
}
}
}
</script>
<style scoped>
</style>
4.新增/user/person访问,返回修改后的用户信息,用于更新sessionStorage里的user
5.优化侧边栏,点击后可路由跳转到对应页面
6.改造vue/src/utils/request.js,增加拦截功能,sessionStorage里的user为空时,自动跳转到登录页
效果:
7.参照用户管理,调整书籍管理,复制user相关代码,user替换成book,vue/src/views/User.vue复制成vue/src/views/Book.vue
<template> <div style="width: 100%; padding: 10px"> <!-- 功能区--> <div style="margin: 10px 0"> <el-button type="primary" @click="add()">新增</el-button> <el-button type="primary">导入</el-button> <el-button type="primary">导出</el-button> </div> <!-- 搜索区--> <div style="margin: 10px 0"> <el-input v-model="search" placeholder="请输入关键字" style="width: 20%" clearable></el-input> <el-button type="primary" style="margin-left: 10px" @click="load">查询</el-button> </div> <el-table :data="tableData" border stripe> <el-table-column prop="id" label="ID" sortable /> <el-table-column prop="name" label="名称" /> <el-table-column prop="price" label="单价" /> <el-table-column prop="author" label="作者" /> <el-table-column prop="createTime" label="出版时间" /> <el-table-column fixed="right" label="操作" min-width="120"> <template #default="scope"> <el-button link type="primary" size="small" @click="handleEdit(scope.row)"> 编辑 </el-button> <el-button link type="primary" size="small">查看</el-button> <el-popconfirm title="确认删除吗?" @confirm="handleDelete(scope.row.id)"> <template #reference> <el-button link type="primary" size="small">删除</el-button> </template> </el-popconfirm> </template> </el-table-column> </el-table> <div style="margin: 10px 0"> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> <el-dialog v-model="dialogVisible" title="用户信息" width="30%"> <el-form :label-position="labelPosition" label-width="auto" :model="form" style="width: 600px"> <el-form-item label="名称"> <el-input v-model="form.name" style="width: 80%"></el-input> </el-form-item> <el-form-item label="单价"> <el-input v-model="form.price" style="width: 80%"></el-input> </el-form-item> <el-form-item label="作者"> <el-input v-model="form.author" style="width: 80%"></el-input> </el-form-item> <el-form-item label="出版时间"> <el-date-picker v-model="form.createTime" type="date" style="width: 80%" clearable></el-date-picker> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="save()"> 确 定 </el-button> </div> </template> </el-dialog> </div> </template> <script> import request from "@/utils/request"; export default { name: 'Book', components: { }, data() { return { form: {}, dialogVisible: false, search: '', currentPage: 1, pageSize: 10, total: 0, tableData: [] } }, created() { this.load() }, methods: { load() { request.get("/book", { params:{ pageNum: this.currentPage, pageSize: this.pageSize, search: this.search } }).then(res=>{ console.log(res) this.tableData = res.data.records this.total = res.data.total }) }, add(){ this.dialogVisible = true this.form = {} }, save(){ if(this.form.id){ //更新 request.put("/book", this.form).then(res => { console.log(res) if(res.code === '0'){ this.$message({ type: "success", message: "更新成功" }) }else { this.$message({ type: "error", message: "res.msg" }) } this.load() //更新后刷新表格数据 this.dialogVisible = false //关闭弹窗 }) } else { //新增 request.post("/book", this.form).then(res => { console.log(res) if(res.code === '0'){ this.$message({ type: "success", message: "新增成功" }) }else { this.$message({ type: "error", message: "res.msg" }) } this.load() //更新后刷新表格数据 this.dialogVisible = false //关闭弹窗 }) } }, handleEdit(row) { this.form = JSON.parse(JSON.stringify(row)) this.dialogVisible = true }, handleDelete(id) { console.log(id) request.delete("/book/" + id).then(res => { if(res.code === '0'){ this.$message({ type: "success", message: "删除成功" }) }else { this.$message({ type: "error", message: "res.msg" }) } this.load() //删除后刷新表格数据 }) }, handleSizeChange() { //改变当前每页个数触发 this.load() }, handleCurrentChange() { //改变当前页码触发 this.load() } } } </script>
com/example/demo/entity/User.java 复制成 com/example/demo/entity/Book.java
package com.example.demo.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.math.BigDecimal; import java.util.Date; @TableName("book") @Data public class Book { @TableId(value = "id",type = IdType.AUTO) private Integer id; private String name; private BigDecimal price; private String author; @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date createTime; }
com/example/demo/mapper/UserMapper.java复制成com/example/demo/mapper/BookMapper.java
package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.Book; public interface BookMapper extends BaseMapper<Book> { }
com/example/demo/controller/UserController.java复制成com/example/demo/controller/BookController.java
package com.example.demo.controller; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.demo.common.Result; import com.example.demo.entity.Book; import com.example.demo.mapper.BookMapper; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/book") public class BookController { //正常Mapper是在Service里引用,Controllerl里引用Service,本案例是为了方便调用,非正规操作 @Resource BookMapper bookMapper; @PostMapping public Result<?> save(@RequestBody Book book){ bookMapper.insert(book); return Result.success(); } @PutMapping public Result<?> update(@RequestBody Book book){ bookMapper.updateById(book); return Result.success(); } @DeleteMapping("/{id}") public Result<?> delete(@PathVariable Long id){ bookMapper.deleteById(id); return Result.success(); } @GetMapping public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(defaultValue = "") String search){ LambdaQueryWrapper<Book> wrapper = Wrappers.<Book>lambdaQuery(); if(StrUtil.isNotBlank(search)){ wrapper.like(Book::getName, search); } Page<Book> bookPage = bookMapper.selectPage(new Page<>(pageNum, pageSize), wrapper); return Result.success(bookPage); } }
数据库新建book表
create table book ( id int auto_increment comment 'ID' primary key, name varchar(255) null comment '名称', price decimal null comment '价格', author varchar(255) null comment '作者', create_time datetime null comment '出版日期' ) comment '书籍';
效果:新增、查询、编辑、删除、分页等用户管理功能,书籍管理都可用
复制后调试过程中出现一个问题,时间字段显示不出来,新增报错。后来发现book这个实体类里createTime的属性写成了Data,而不是Date,所以查询和插入都失败
8. 优化左侧菜单栏高亮显示,优化前浏览器地址直接输入http://localhost:9876/book,书籍管理节点不高亮,现在是浏览器直接输入也高亮
效果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异