当然!下面给你一个基于 Vue.js 的图书管理系统前端界面设计思路,并附带关键页面的设计要点和可参考的 Vue 组件组织方案,方便你快速落地。
🎨 系统界面模块规划
1. 登录/注册页
- 简洁表单:用户名、密码输入框 + 登录/注册按钮
- 背景可配合图书元素或书架插画,提升用户体验
- 成功后路由跳转到系统主界面
2. 主界面布局
- 采用经典三栏布局:
- 左侧:侧边栏菜单(书籍管理、分类管理、借阅管理、用户管理)
- 中间:内容区域,动态渲染各功能页面
- 顶部:系统标题、当前用户信息、退出登录
<template>
<div class="h-screen flex">
<Sidebar />
<div class="flex-1 flex flex-col">
<HeaderBar />
<router-view class="p-6 bg-gray-50 flex-1 overflow-auto" />
</div>
</div>
</template>
📚 功能页面设计
📖 书籍管理页
- 功能:新增/编辑/删除/搜索书籍
- 表格展示书籍信息:封面、书名、作者、ISBN、分类、库存状态
- 顶部操作栏:搜索框 + 新增书籍按钮
- 表格行操作:编辑、删除
<template>
<div>
<div class="flex justify-between mb-4">
<input v-model="search" class="border rounded p-2 w-60" placeholder="搜索书名/作者..." />
<button @click="openAddBook" class="bg-blue-500 text-white px-4 py-2 rounded">新增书籍</button>
</div>
<BookTable :books="filteredBooks" @edit="editBook" @delete="deleteBook" />
</div>
</template>
📂 分类管理页
- 表格展示书籍分类:分类ID、分类名
- 支持新增、编辑、删除分类
- 表单:弹窗形式输入/修改分类信息
📝 借阅管理页
- 展示借阅记录:借阅人、书籍、借阅时间、归还时间、状态(已归还/未归还)
- 支持记录归还操作
👤 用户管理页(可选)
- 针对管理员系统:列出用户信息,支持封禁/解封用户等操作
💡 核心技术要点
✅ 路由管理:使用 Vue Router 管理各功能页面路由
✅ 状态管理:Vuex(或 pinia)集中管理书籍、分类、用户状态
✅ 组件化:将页面拆分成
- 侧边栏组件
Sidebar.vue
- 头部栏组件
HeaderBar.vue
- 表格组件
BookTable.vue
- 模态窗口组件
Modal.vue
等
✅ UI 框架:推荐配合 Element Plus 或 Ant Design Vue 来快速搭建表格、表单、弹窗、分页等
✅ 样式:TailwindCSS(灵活美观)或 SCSS 自定义样式
🔗 目录结构示例
src/
components/
Sidebar.vue
HeaderBar.vue
BookTable.vue
BookForm.vue
views/
Login.vue
Dashboard.vue
Books.vue
Categories.vue
Borrow.vue
Users.vue
store/
index.js
books.js
router/
index.js
App.vue
main.js
🌟 额外可拓展功能
- 图书封面上传
- 图书分类树状展示
- 借阅逾期提醒
- 数据可视化统计(折线/柱状图显示借阅数量、用户增长)
当然!这里给你一个 基于 Vue 3 + Composition API 的书籍管理页面完整示例,包含:搜索、表格、编辑、新增、删除等功能,并配合 Element Plus 作为 UI 框架,方便你快速上手并实际使用。
✅ 1. 安装依赖
npm install element-plus axios
在 main.js
里全局引入 Element Plus:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router).use(store).use(ElementPlus).mount('#app')
✅ 2. Books.vue 页面
<template>
<div>
<el-card>
<div class="flex justify-between mb-4">
<el-input
v-model="searchKeyword"
placeholder="搜索书名或作者"
style="width: 300px"
clearable
@clear="loadBooks"
>
<template #suffix>
<el-icon><Search /></el-icon>
</template>
</el-input>
<el-button type="primary" @click="openAddDialog">新增书籍</el-button>
</div>
<el-table :data="filteredBooks" stripe style="width: 100%">
<el-table-column label="封面" width="100">
<template #default="{ row }">
<el-image :src="row.cover" style="width: 60px; height: 80px" />
</template>
</el-table-column>
<el-table-column prop="title" label="书名" />
<el-table-column prop="author" label="作者" />
<el-table-column prop="isbn" label="ISBN" width="140" />
<el-table-column prop="category" label="分类" />
<el-table-column label="操作" width="160">
<template #default="{ row }">
<el-button type="primary" text size="small" @click="openEditDialog(row)">编辑</el-button>
<el-button type="danger" text size="small" @click="deleteBook(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
<el-form :model="bookForm" label-width="80px">
<el-form-item label="书名">
<el-input v-model="bookForm.title" />
</el-form-item>
<el-form-item label="作者">
<el-input v-model="bookForm.author" />
</el-form-item>
<el-form-item label="ISBN">
<el-input v-model="bookForm.isbn" />
</el-form-item>
<el-form-item label="分类">
<el-input v-model="bookForm.category" />
</el-form-item>
<el-form-item label="封面URL">
<el-input v-model="bookForm.cover" placeholder="图片地址" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitBook">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
const books = ref([])
const searchKeyword = ref('')
const dialogVisible = ref(false)
const dialogTitle = ref('新增书籍')
const bookForm = ref({
id: null,
title: '',
author: '',
isbn: '',
category: '',
cover: ''
})
// 加载书籍数据
const loadBooks = async () => {
// 模拟接口获取数据
const response = await axios.get('/api/books') // 替换为你的后端接口
books.value = response.data
}
// 搜索过滤
const filteredBooks = computed(() => {
if (!searchKeyword.value) return books.value
const keyword = searchKeyword.value.toLowerCase()
return books.value.filter(
book =>
book.title.toLowerCase().includes(keyword) ||
book.author.toLowerCase().includes(keyword)
)
})
// 打开新增书籍弹窗
const openAddDialog = () => {
dialogTitle.value = '新增书籍'
bookForm.value = {
id: null,
title: '',
author: '',
isbn: '',
category: '',
cover: ''
}
dialogVisible.value = true
}
// 打开编辑弹窗
const openEditDialog = (book) => {
dialogTitle.value = '编辑书籍'
bookForm.value = { ...book }
dialogVisible.value = true
}
// 保存(新增/编辑)
const submitBook = async () => {
try {
if (bookForm.value.id) {
// 编辑
await axios.put(`/api/books/${bookForm.value.id}`, bookForm.value)
ElMessage.success('更新成功')
} else {
// 新增
await axios.post('/api/books', bookForm.value)
ElMessage.success('新增成功')
}
dialogVisible.value = false
loadBooks()
} catch (error) {
ElMessage.error('操作失败')
}
}
// 删除
const deleteBook = async (id) => {
try {
await ElMessageBox.confirm('确定要删除这本书吗?', '提示', { type: 'warning' })
await axios.delete(`/api/books/${id}`)
ElMessage.success('删除成功')
loadBooks()
} catch {
// 用户取消或请求失败
}
}
onMounted(loadBooks)
</script>
<style scoped>
.mb-4 {
margin-bottom: 1rem;
}
.flex {
display: flex;
align-items: center;
}
.justify-between {
justify-content: space-between;
}
</style>
✅ 3. 说明
✅ 数据接口
/api/books
:获取书籍列表(GET)/api/books/:id
:修改书籍(PUT)/api/books/:id
:删除书籍(DELETE)/api/books
:新增书籍(POST)
你可以用 JSON Server 或 Node.js 快速模拟后端接口。
✅ 功能点
- 搜索框支持模糊搜索
- 表格列表展示基本书籍信息
- 编辑、新增使用同一个弹窗
- 删除带有确认弹窗
✅ UI
- 使用 Element Plus 的表格、弹窗、输入框、消息提示,界面简洁好用。
当然!这里给你一个基于 Node.js + Express 的简易 RESTful API,可以配合你刚才的 Vue 前端一起使用,快速跑起来做联调或测试。下面内容包括完整后端代码,并且使用内存数据(不依赖数据库,适合开发阶段)。
✅ 1. 初始化 Node 项目
在项目根目录新建 server
文件夹,然后进入并执行:
npm init -y
npm install express cors
✅ 2. 创建 index.js
在 server/index.js
中写入以下内容:
const express = require('express')
const cors = require('cors')
const app = express()
const port = 3000
app.use(cors())
app.use(express.json())
// 模拟书籍数据(内存数组)
let books = [
{
id: 1,
title: '三体',
author: '刘慈欣',
isbn: '9787536692930',
category: '科幻',
cover: 'https://img2.doubanio.com/view/subject/l/public/s6384944.jpg'
},
{
id: 2,
title: '活着',
author: '余华',
isbn: '9787506365437',
category: '小说',
cover: 'https://img2.doubanio.com/view/subject/l/public/s27264181.jpg'
}
]
// 查询所有书籍
app.get('/api/books', (req, res) => {
res.json(books)
})
// 新增书籍
app.post('/api/books', (req, res) => {
const newBook = req.body
newBook.id = Date.now() // 简单生成唯一ID
books.push(newBook)
res.json(newBook)
})
// 更新书籍
app.put('/api/books/:id', (req, res) => {
const bookId = Number(req.params.id)
const index = books.findIndex(b => b.id === bookId)
if (index !== -1) {
books[index] = { ...books[index], ...req.body }
res.json(books[index])
} else {
res.status(404).json({ error: '未找到书籍' })
}
})
// 删除书籍
app.delete('/api/books/:id', (req, res) => {
const bookId = Number(req.params.id)
const index = books.findIndex(b => b.id === bookId)
if (index !== -1) {
books.splice(index, 1)
res.json({ message: '删除成功' })
} else {
res.status(404).json({ error: '未找到书籍' })
}
})
app.listen(port, () => {
console.log(`后端接口已启动: http://localhost:${port}`)
})
✅ 3. 启动服务
在 server
目录执行:
node index.js
你会看到:
后端接口已启动: http://localhost:3000
✅ 4. 在 Vue 前端中配置 API 地址
将你前端中 Axios 的请求地址替换成:
// 例如在 Books.vue
const response = await axios.get('http://localhost:3000/api/books')
🔥 这样你就可以:
✅ 本地跑起 Vue 前端(http://localhost:5173)
✅ 同时本地跑起 Node 后端(http://localhost:3000)
✅ 完全自测新增/编辑/删除书籍功能。
发表回复