当前位置: 首页 > news >正文

【AI编程工具】快速搭建图书管理系统

大家好,我是工藤学编程 🦉一个正在努力学习的小博主,期待你的关注
实战代码系列最新文章😉C++实现图书管理系统(Qt C++ GUI界面版)
SpringBoot实战系列🐷【SpringBoot实战系列】SpringBoot3.X 整合 MinIO 存储原生方案
分库分表分库分表之实战-sharding-JDBC分库分表执行流程原理剖析
消息队列深入浅出 RabbitMQ-RabbitMQ消息确认机制(ACK)

本文章目录

  • 基于Vue 3 + JSON Server 实现轻量图书管理系统
    • 一、技术栈与环境准备
      • 1. 技术栈选型
      • 2. 环境搭建步骤
        • 步骤1:创建Vue项目
        • 步骤2:安装JSON Server
    • 二、JSON Server 模拟后端接口
      • 1. 创建接口数据文件
      • 2. 启动JSON Server
    • 三、Vue前端核心功能实现
      • 1. 项目目录结构
      • 2. 核心配置实现
        • (1)Axios封装(处理请求拦截、基础路径)
        • (2)路由配置(含登录权限控制)
        • (3)入口文件配置(挂载路由)
      • 3. 核心页面功能实现
        • (1)注册页面(Register.vue)
        • (2)登录页面(Login.vue)
        • (3)图书列表页(Home.vue)
        • (4)导航栏组件(Navbar.vue)
    • 四、项目运行与功能演示
      • 1. 启动项目
        • 步骤1:启动JSON Server(后端接口)
        • 步骤2:启动Vue项目(前端)
      • 2. 功能演示流程

基于Vue 3 + JSON Server 实现轻量图书管理系统

AI提示词如下:

我要实现一个图书管理系统,请你用vue相关代码,以及生成json文件作为接口返回内容,功能包括注册、登录,分类,查询即可

在前端学习中,“图书管理系统”是覆盖“用户认证+数据CRUD”的经典案例。本文将用Vue 3(Composition API)+ JSON Server搭建系统,实现注册、登录、图书分类、模糊查询四大核心功能,无需后端开发,10分钟即可跑通完整流程。

一、技术栈与环境准备

1. 技术栈选型

  • 前端核心:Vue 3(Vite构建,Composition API)
  • 路由管理:Vue Router 4(控制页面权限)
  • 网络请求:Axios(处理接口调用)
  • 模拟后端:JSON Server(基于JSON文件提供RESTful接口)
  • 样式辅助:Tailwind CSS(快速实现简洁界面,可选)

2. 环境搭建步骤

步骤1:创建Vue项目

打开终端,执行以下命令创建Vite+Vue 3项目:

# 创建项目(项目名:book-management-system)
npm create vite@latest book-management-system -- --template vue# 进入项目目录
cd book-management-system# 安装依赖
npm install# 安装额外依赖(路由、axios)
npm install vue-router@4 axios
步骤2:安装JSON Server

JSON Server可将JSON文件转为可访问的API接口,全局安装:

npm install -g json-server

二、JSON Server 模拟后端接口

1. 创建接口数据文件

在项目根目录新建db.json文件(模拟数据库),包含用户表(users)图书表(books) ,初始数据如下:

{list: [{category:"literature",bookImg:"http://t14.baidu.com/it/u=2285971984,1142952378&fm=224&app=112&f=JPEG?w=500&h=500",  id:1,author:"Charlotte Brontë",price:"36",bookName:"Jane Eyre"},{category:"literature",bookImg:"https://pic.rmb.bdstatic.com/acf7204f9c18b91bd8e3ce3d09961118.jpeg",  id:2,author:"Victor Hugo",price:"33",bookName:"The Hunchback of Notre-Dame"},{category:"education",bookImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fbao%2Fuploaded%2Fi1%2F1899623276%2FTB1IRy9hnlYBeNjSszcXXbwhFXa_%21%210-item_pic.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1731158616&t=f5b9cf04e7f605e74c0b0cb0c2e8896e",  id:3,author:"Plato",price:"78",bookName:"The Republic"},{category:"life",bookImg:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcbu01.alicdn.com%2Fimg%2Fibank%2FO1CN01lwQysa2L7SnTLGSPy_%21%214038439645-0-cib.jpg&refer=http%3A%2F%2Fcbu01.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1731159003&t=fb0a6f17e841bf5b7b4ebfa143f14d17",  id:4,author:"Viktor E. Frankl",price:"75",bookName:"Man's Search for Meaning"}]

2. 启动JSON Server

在终端执行命令,启动接口服务(端口3000,避免与Vue项目冲突):

json-server --watch db.json --port 3000

启动成功后,可通过以下地址访问接口:

  • 查看所有用户:http://localhost:3000/users
  • 查看所有图书:http://localhost:3000/books
  • 新增用户(注册):POST http://localhost:3000/users
  • 图书查询:GET http://localhost:3000/books?q=关键词(模糊查询)

三、Vue前端核心功能实现

1. 项目目录结构

先梳理前端文件:
在这里插入图片描述

2. 核心配置实现

(1)Axios封装(处理请求拦截、基础路径)

新建src/utils/request.js,统一管理接口请求:

import axios from 'axios'// 创建Axios实例
const request = axios.create({baseURL: 'http://localhost:3000', // JSON Server地址timeout: 5000
})// 请求拦截器(可选:添加token)
request.interceptors.request.use(config => {// 从localStorage获取token(登录后存储)const token = localStorage.getItem('token')if (token) {config.headers.Authorization = `Bearer ${token}`}return config},error => Promise.reject(error)
)// 响应拦截器(统一处理错误)
request.interceptors.response.use(response => response.data,error => {alert('接口请求失败:' + error.message)return Promise.reject(error)}
)export default request
(2)路由配置(含登录权限控制)

新建src/router/index.js,区分“公开页面”和“需登录页面”:

import { createRouter, createWebHistory } from 'vue-router'
import Login from '../views/Login.vue'
import Register from '../views/Register.vue'
import BookList from '../views/BookList.vue'// 路由规则
const routes = [{ path: '/', redirect: '/login' }, // 根路径重定向到登录页{ path: '/login', component: Login, meta: { isPublic: true } }, // 公开页面{ path: '/register', component: Register, meta: { isPublic: true } }, // 公开页面{ path: '/book-list', component: BookList } // 需登录页面
]const router = createRouter({history: createWebHistory(),routes
})// 路由守卫(未登录拦截)
router.beforeEach((to, from, next) => {// 非公开页面且无token,跳转到登录页if (!to.meta.isPublic && !localStorage.getItem('token')) {next('/login')} else {next()}
})export default router
(3)入口文件配置(挂载路由)

修改src/main.js,引入路由和Axios:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import request from './utils/request'const app = createApp(App)// 全局挂载Axios(方便组件内通过this.$request调用)
app.config.globalProperties.$request = requestapp.use(router).mount('#app')

3. 核心页面功能实现

(1)注册页面(Register.vue)

实现“用户名+密码”注册,调用JSON Server的POST接口新增用户:

<template><div class="register"><div class="backgroundImage"></div><div class="register_container"><h1>Book Management System</h1><!-- Registration form, binding user information and validation rules --><el-form class="register_form" :model="userInfo" :rules="rules" @keyup.enter="registerIn" ref="ref_form"><el-form-item prop="userName"><el-input placeholder="Please enter your username" v-model.trim="userInfo.userName"><template #prepend><el-icon><avatar /></el-icon></template></el-input></el-form-item><el-form-item prop="password"><el-input placeholder="Please enter your password" show-password v-model.trim="userInfo.password"><template #prepend><el-icon><key/></el-icon></template></el-input></el-form-item><!-- Registration button, triggers the registration process when clicked --><el-button type="primary" class="register_submit" @click="registerIn">Register</el-button><!-- Login link, redirects to the login page when clicked --><div class="login_register" @click="toLogin">Already have an account? Go to login</div></el-form></div></div>
</template><script setup>
import router from "@/router";
import { ElMessage } from "element-plus";
import { reactive, ref } from "vue";
// Reference to the form
const ref_form = ref(null);
// Reactive user information object
const userInfo = reactive({userName: '',password: ''
});
// Form validation rules
const rules = {userName: [{ required: true, trigger: 'blur', message: 'Username cannot be empty' }],password: [{ required: true, trigger: 'blur', message: 'Password cannot be empty' }],
};
// Registration method, validates the form and calls getRegisterInfo method
const registerIn = () => {ref_form.value.validate((val) => {if (val) {getRegisterInfo();}});
};
// Get registration information method, simulates successful registration and redirects to the login page
const getRegisterInfo = () => {ElMessage({message: 'Registration successful',type: 'success'});router.push('/login');
};
// Method to redirect to the login page
const toLogin = () => {router.push('/login');
};
</script>
<style lang="less" scoped>
@-webkit-keyframes fedenum {0% {opacity: 0;}100% {opacity: 1;}
}
.register {display: flex;justify-content: center;align-items: center;height: 100vh;position: relative; 
}.backgroundImage {height: 100%;width: 100%; background-image: url("../assets/bj.jpg");background-repeat: no-repeat;background-size: cover; background-position: center; position: absolute; top: 0;left: 0;z-index: 0; 
}.register_container {animation: fadenum 1s ease;position: relative; z-index: 1;width: 400px;min-height: 273px;text-align: center;background-color: #fff;border-radius: 10px;padding: 20px;
}
el-icon {height: 30px !important;
}h1 {font-size: 24px;transition: all 1s;font-weight: bold;margin-bottom: 36px;
}
.el-card {border-radius: 20px;
}
.register_form {.register_submit {width: 100%;height: 50px;border-radius: 20px;margin-bottom: 10px;}.login_register {width: 11rem;font-size: 0.875rem;margin: 0 auto;}:deep(.el-input-group__prepend) {padding: 0 10px;}
}
</style>
(2)登录页面(Login.vue)

验证用户名密码,登录成功后存储token(模拟JWT)并跳转图书列表:

<template><div class="login"><div class="backgroundImage"></div><div class="login_container"><h1>Book Management System</h1><!-- Login form, binding user information and validation rules --><el-form class="login_form" :model="userInfo" :rules="rules" @keyup.enter="loginIn" ref="ref_form"><el-form-item prop="userName"><el-input placeholder="Please enter your username" v-model.trim="userInfo.userName"><template #prepend><el-icon><avatar /></el-icon></template></el-input></el-form-item><el-form-item prop="password"><el-input placeholder="Please enter your password" show-password v-model.trim="userInfo.password"><template #prepend><el-icon><key/></el-icon></template></el-input></el-form-item><!-- Login button, triggers login operation when clicked --><el-button type="primary" class="login_submit" @click="loginIn">Login</el-button><!-- Register link, redirects to register page when clicked --><div class="login_register" @click="toRegister">Register</div></el-form></div></div>
</template><script setup>
import { userStore } from "@/common/js/store";
import router from "@/router";
import { ElMessage } from "element-plus";
import { reactive, ref } from "vue";
// Reference to the form
const ref_form = ref(null)
// Reactive user information object
const userInfo = reactive({userName: '',password: ''
})
// Form validation rules
const rules = {userName: [{ required: true, trigger: 'blur', message: 'Username cannot be empty' }],password: [{ required: true, trigger: 'blur', message: 'Password cannot be empty' }],
}
// Login method, validates the form and calls getUserInfo method
const loginIn = () => {ref_form.value.validate((val) => {if (val) {getUserInfo()}})
}
// Get user information method, simulates successful login and redirects to the home page
const getUserInfo = () => {userStore.userName = userInfo.userName;localStorage.setItem('token', '100') // Simulate setting a tokenElMessage({message: 'Login successful',type: 'success'})router.push('/home') // After successful login, redirect to the home page
}
// Method to redirect to the register page
const toRegister = () => {router.push('/register')
}
</script>
<style lang="less" scoped>
@-webkit-keyframes fedenum {0% {opacity: 0;}100% {opacity: 1;}
}
.login {display: flex;justify-content: center;align-items: center;height: 100vh; position: relative; 
}.backgroundImage {height: 100%;width: 100%; background-image: url("../assets/bj.jpg");background-repeat: no-repeat;background-size: cover; background-position: center;position: absolute; top: 0;left: 0;z-index: 0; 
}.login_container {animation: fadenum 1s ease;position: relative; z-index: 1;width: 400px;min-height: 273px;text-align: center;background-color: #fff;border-radius: 10px;padding: 20px;
}el-icon {height: 30px !important;
}
h1 {font-size: 24px;transition: all 1s;font-weight: bold;margin-bottom: 36px;
}
.el-card {border-radius: 20px;
}
.login_form {.login_submit {width: 100%;height: 50px;border-radius: 20px;margin-bottom: 10px;}.login_register {width: 6.25rem;font-size: 0.875rem;margin: 0 auto;}:deep(.el-input-group__prepend) {padding: 0 10px;}
}
</style>
(3)图书列表页(Home.vue)

实现图书分类筛选模糊查询,核心功能:

  • 加载所有图书
  • 按“前端开发/后端开发/计算机基础”分类筛选
  • 按书名/作者模糊查询
<template><div class="home"><!-- Use Element UI's el-container component to create a container for layout --><el-container><!-- Use el-aside component to create a sidebar --><el-aside width="200px"><!-- Include the Aside component to display the sidebar content --><!-- :handleCollapse and :isCollapse are used to control the collapse state of the sidebar --><!-- @updateCategory listens for the updateCategory event emitted by the child component to update the current category --><Aside :handleCollapse='handleCollapse' :isCollapse='isCollapse' @updateCategory="handleCategoryChange"/></el-aside><el-container><!-- Use el-header component to create the header area --><el-header><!-- Include the Header component to display the header content --><!-- :handleCollapse and :isCollapse are used to control the collapse state of the header --><Header :handleCollapse='handleCollapse' :isCollapse='isCollapse'/></el-header><el-main><!-- Use el-main component to create the main content area --><!-- Include the Main component to display the main content --><!-- :category is used to pass the current category to the Main component --><Main :category="currentCategory"/></el-main></el-container></el-container></div>
</template><script setup>
import Header from '@/components/Header.vue'
import Aside from '@/components/Aside.vue'
import Main from '@/components/Main.vue'
import { userStore } from "@/common/js/store";
import { ref } from 'vue'// Define a reactive variable to control the collapse state of the sidebar and header
const isCollapse = ref(false)
// Define a reactive variable to store the currently selected category
const currentCategory = ref('')
// Define a method to toggle the collapse state of the sidebar and header
const handleCollapse = () => {isCollapse.value = !isCollapse.value
}
// Define a method to handle category changes
// When the Aside component emits an updateCategory event, this method updates the value of currentCategory
const handleCategoryChange = (category) => {currentCategory.value = category
}
</script>
<style lang="less" scoped>
.el-aside{width: auto;background-color: #544c64;overflow: hidden;
}
.el-container{height: 100vh;
}
.el-main{display: flex;
}
.el-header{background-color: #fff;
}
</style>
(4)导航栏组件(Navbar.vue)

实现“用户名显示”和“退出登录”功能:

<template><!-- Create a vertical navigation menu with custom active text color, background color, and text color --><!-- Whether to collapse, bound to the isCollapse variable --><el-menuclass="el-menu-vertical-demo"active-text-color="#15df84"background-color="#545c64"text-color="#fff":collapse="isCollapse"><!-- Define a library icon area containing an icon and text --><div class="library-icon"><img src="../assets/library-icon.png"> <!-- Library icon --><p>Library Management System</p></div><!-- Define a submenu for book management --><el-sub-menu index="1"><template #title><el-icon><document /></el-icon><span>Book Management</span></template><!-- Define three menu items that trigger the updateCategory method and pass category parameters when clicked --><el-menu-item index="1-1" @click="updateCategory('literature')">Literature</el-menu-item><el-menu-item index="1-2" @click="updateCategory('education')">Education</el-menu-item><el-menu-item index="1-3" @click="updateCategory('life')">Life</el-menu-item></el-sub-menu></el-menu>
</template>
<script setup>
// Receive the isCollapse property from the parent component
const { isCollapse } = defineProps(['isCollapse'])
// Define an event emitter to send events to the parent component
const emit = defineEmits(['updateCategory'])// Method to update category, triggers the updateCategory event and passes category parameters
const updateCategory = (category) => {emit('updateCategory', category)
}
</script>
<style lang = 'less' scoped>
.el-radio-button_inner{padding: 0;
}
.el-menu--collapse{border: none;
}
.el-menu:not(.el-menu--collapse){width: 200px;min-height: 800px;border: none;
}
.library-icon{display: flex;align-items: center;font-weight: 600;height: 60px;background-color: #fff;white-space: nowrap;padding-left: 15px;
}
img{width: 45px;height: 40px;margin-right: 10px;
}
p{font-size: 10px;font-weight: bold;
}
</style>

四、项目运行与功能演示

1. 启动项目

步骤1:启动JSON Server(后端接口)
json-server --watch db.json --port 3000
步骤2:启动Vue项目(前端)

打开新终端,进入项目目录:

npm run dev

Vue项目默认启动在http://localhost:5173

2. 功能演示流程

  1. 注册:访问http://localhost:5173/register,输入用户名(如test123)和密码(如123456),注册成功后跳登录页。
    在这里插入图片描述

  2. 登录:输入刚注册的账号密码,登录成功后跳图书列表页。
    在这里插入图片描述

  3. 图书分类:点击“前端开发”“后端开发”等按钮,可筛选对应分类的图书。
    在这里插入图片描述

  4. 模糊查询:在搜索框输入关键词(如Jan),实时筛选图书。
    在这里插入图片描述

  5. 退出登录:点击导航栏“退出登录”,清除缓存并返回登录页。

在这里插入图片描述

觉得有用请点赞收藏!
如果有相关问题,欢迎评论区留言讨论~


文章转载自:

http://jBfu6uiV.wsrcy.cn
http://PWSZ0Ogt.wsrcy.cn
http://O8XwJmyI.wsrcy.cn
http://OJsMsUEV.wsrcy.cn
http://LD4U0GSn.wsrcy.cn
http://OOesB853.wsrcy.cn
http://qkUKHvfI.wsrcy.cn
http://RjW5UvoM.wsrcy.cn
http://Lx9VpT6c.wsrcy.cn
http://nxGZzDi4.wsrcy.cn
http://aTW0YCy7.wsrcy.cn
http://t5K9yPfI.wsrcy.cn
http://B5eAAaGk.wsrcy.cn
http://PSXZgUGL.wsrcy.cn
http://wL68O1tT.wsrcy.cn
http://EMS7brer.wsrcy.cn
http://cAJpoB9X.wsrcy.cn
http://68Pa9sVE.wsrcy.cn
http://mTNcZl8C.wsrcy.cn
http://j8zzfhst.wsrcy.cn
http://ihUANRzU.wsrcy.cn
http://1wUrGphE.wsrcy.cn
http://MuyjNWJS.wsrcy.cn
http://I0iFtBg3.wsrcy.cn
http://CE2jJY5e.wsrcy.cn
http://FHMv9EZL.wsrcy.cn
http://wZPPvyft.wsrcy.cn
http://edoWT6b7.wsrcy.cn
http://O4zZ8eKQ.wsrcy.cn
http://1wccvcU0.wsrcy.cn
http://www.dtcms.com/a/367866.html

相关文章:

  • 安卓学习 之 EditText 控件
  • 2025职教技能大赛汽车制造与维修赛道速递-产教融合实战亮剑​
  • java面试中经常会问到的zookeeper问题有哪些(基础版)
  • 光伏项目无人机踏勘--如何使用无人机自动航线规划APP
  • jenkins加docker 部署项目
  • linux离线安装elasticsearch8.19.3
  • Jenkins环境搭建与使⽤
  • Jenkins 监控方案:Prometheus + Grafana 实践
  • 【论文阅读】Security of Language Models for Code: A Systematic Literature Review
  • 神经网络算法各种层的原理(基于Keras)--输入层,全连接层,卷积层,池化层,嵌入层,长短期记忆网络层等
  • Github | MoneyPrinterTurbo:自动化视频内容生成系统
  • JUnit入门:Java单元测试全解析
  • 如何下载B站视频,去水印,翻译字幕
  • 脚本语言的大浪淘沙或百花争艳
  • Redis中的hash数据类型
  • 如何安全地删除与重建 Elasticsearch 的 .watches 索引
  • HDFS存储农业大数据的秘密是什么?高级大豆数据分析与可视化系统架构设计思路
  • uni-app iOS 文件调试常见问题与解决方案:结合 itools、克魔、iMazing 的实战经验
  • 解析豆科系统发育冲突原因
  • 五分钟XML速成
  • 《LangChain从入门到精通》系统学习教材大纲
  • 华为云 OBS:数字时代的数据存储与价值挖掘利器
  • Claude Code PM 深度实战指南:AI驱动的GitHub项目管理与并行协作
  • paimon实战 -- 阿里基于StarRocks 与 Paimon 实现的实时分析黑科技
  • 开源定时器教程:Quartz与XXL-JOB全面对比与实践
  • Day21_【机器学习—决策树(3)—剪枝】
  • finalize() 方法介绍
  • IDE mac M芯片安装报错:如何解决“InsCode.app 已损坏”,无法打开
  • Qt信号与槽机制全面解析
  • Qt实现背景滚动