基于 Vue 3 和 Element Plus 构建图书管理系统

基于 Vue 3 和 Element Plus 构建图书管理系统

本文将介绍如何使用 Vue 3 和 Element Plus 构建一个简单的图书管理系统。这个系统将包括以下功能:

  • 添加新书
  • 显示图书列表
  • 分页显示图书
  • 删除图书

相关链接

接口地址
elementplus中文地址

项目结构

我们的项目结构如下:

plaintext 复制代码
src/
├── components/
│   └── BookManager.vue
├── App.vue
└── main.js

BookManager.vue 是我们主要的组件文件,它包含了图书管理的所有逻辑。App.vuemain.js 是 Vue 3 项目的基础文件。

引入必要的库

main.js 文件中,我们引入 Vue 3 和 Element Plus,并进行初始化:

javascript 复制代码
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

图书管理组件

components/BookManager.vue 文件中,我们将实现图书管理功能。

模板部分
html 复制代码
<template>
  <div class="button-container">
    <el-button type="primary" @click="dialogFormVisible = true">
      新增图书
    </el-button>
  </div>
  <el-dialog v-model="dialogFormVisible" title="新增图书" width="300px">
    <el-form :model="form" label-position="right" label-width="100px">
      <el-form-item label="书名">
        <el-input v-model="form.bookname" />
      </el-form-item>
      <el-form-item label="作者">
        <el-input v-model="form.author" />
      </el-form-item>
      <el-form-item label="出版社">
        <el-input v-model="form.publisher" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="addBook">提交</el-button>
      </div>
    </template>
  </el-dialog>

  <el-table :data="paginatedBooks" style="width: 100%">
    <el-table-column prop="id" label="ID" width="80" />
    <el-table-column prop="bookname" label="书名" width="120" />
    <el-table-column prop="author" label="作者" width="120" />
    <el-table-column prop="publisher" label="出版社" width="120" />
    <el-table-column prop="createdAt" label="创建时间" width="220" />
    <el-table-column prop="updatedAt" label="更新时间" width="220" />
    <el-table-column label="选项操作" min-width="100">
      <template #default="scope">
        <el-button
            link
            type="danger"
            size="small"
            @click.prevent="deleteRow(scope.row.id)"
        >
          删除
        </el-button>
      </template>
    </el-table-column>
  </el-table>

  <div class="pagination-container">
    <el-pagination
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-size="pageSize"
        :total="books.length"
        layout="prev, pager, next"
        style="margin-top: 20px;"
    />
  </div>
</template>

在模板部分,我们使用 Element Plus 的组件来创建一个对话框,用于添加新书,并显示图书列表和分页功能。

脚本部分
javascript 复制代码
<script setup>
import { ref, onMounted, computed } from 'vue';
import { ElMessage } from 'element-plus';
import axios from 'axios';

const dialogFormVisible = ref(false);
const books = ref([]);
const form = ref({
  bookname: '',
  author: '',
  publisher: ''
});
const currentPage = ref(1);
const pageSize = ref(10);

const getBooksAll = async () => {
  const config = {
    method: 'get',
    url: 'http://ajax-api.itheima.net/api/books',
  };
  try {
    const response = await axios(config);
    if (Array.isArray(response.data.data)) {
      books.value = response.data.data.sort((a, b) => a.id - b.id);
    } else {
      throw new Error("数据格式错误");
    }
  } catch (error) {
    console.log(error);
    ElMessage({
      showClose: true,
      message: error.message || error,
      type: 'error',
    });
  }
};

const paginatedBooks = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value;
  return books.value.slice(start, start + pageSize.value);
});

const handleCurrentChange = (newPage) => {
  currentPage.value = newPage;
};

const addBook = async () => {
  const config = {
    method: 'post',
    url: "http://ajax-api.itheima.net/api/books",
    headers: {
      'Content-Type': 'application/json'
    },
    data: JSON.stringify(form.value)
  };
  try {
    await axios(config);
    ElMessage({
      showClose: true,
      message: '添加图书成功',
      type: "success",
    });
    await getBooksAll();
    form.value = { bookname: '', author: '', publisher: '' };
    dialogFormVisible.value = false;
  } catch (error) {
    console.log(error);
  }
};

const deleteRow = async (id) => {
  const config = {
    method: 'delete',
    url: `http://ajax-api.itheima.net/api/books/${id}`,
    headers: {
      'User-Agent': 'Apifox/1.0.0 (https://apifox.com)'
    }
  };
  try {
    await axios(config);
    await getBooksAll();
    ElMessage({
      showClose: true,
      message: '删除成功',
      type: 'success',
    });
  } catch (error) {
    console.log(error);
  }
};

onMounted(async () => {
  await getBooksAll();
});
</script>
样式部分
css 复制代码
<style scoped>
.button-container {
  margin: 20px 0;
  padding-left: 10px;
}
.pagination-container {
  display: flex;
  justify-content: center;
  margin-top: 5px;
}
</style>

关键实现细节

  1. 获取图书列表

    使用 axios 发送 GET 请求,从服务器获取图书列表,并将其存储在 books 变量中。使用 onMounted 钩子在组件挂载时调用 getBooksAll 方法。

  2. 分页显示图书

    使用 computed 计算属性 paginatedBooks 来实现分页功能,根据当前页码和每页显示的数量来切割图书列表。

  3. 添加新书

    使用 axios 发送 POST 请求,将新书信息发送到服务器。成功添加后,刷新图书列表,并重置表单和对话框状态。

  4. 删除图书

    使用 axios 发送 DELETE 请求,根据图书 ID 删除图书。成功删除后,刷新图书列表。

  5. 消息提示

    使用 Element Plus 的 ElMessage 组件在操作成功或失败时显示消息提示。

相关推荐
Joyee69120 分钟前
RN 的初版架构——通信机制
前端·react native
Swift社区22 分钟前
从 0 到 1 构建一个完整的 AGUI 前端项目的流程在 ESP32 上运行
前端·算法·职场和发展
fox_23 分钟前
JS: 实现扁平化函数 flat
javascript
剽悍一小兔28 分钟前
小程序到底用Store还是LocalStorage ?
javascript
一只小风华~41 分钟前
学习笔记:Vue Router 中的链接匹配机制与样式控制
前端·javascript·vue.js·笔记·学习·ecmascript
Jerry_Rod1 小时前
react+umijs 项目快速学习
前端·react.js
京东云开发者1 小时前
浅析cef在win和mac上的适配
前端
uhakadotcom1 小时前
在chrome浏览器插件之中,options.html和options.js常用来做什么事情
前端·javascript·面试
西瓜树枝1 小时前
Chrome 扩展开发从入门到实践:以 Cookie 跨页提取工具为例,拆解核心模块与交互逻辑
前端·javascript·chrome