基于 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 组件在操作成功或失败时显示消息提示。

相关推荐
源心锁1 小时前
👋 手搓 gzip 实现的文件分块压缩上传
前端·javascript
源心锁1 小时前
丧心病狂!在浏览器全天候记录用户行为排障
前端·架构
GIS之路1 小时前
GDAL 实现投影转换
前端
phltxy2 小时前
从零入门JavaScript:基础语法全解析
开发语言·javascript
烛阴2 小时前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
BD_Marathon2 小时前
SpringBoot——辅助功能之切换web服务器
服务器·前端·spring boot
Kagol2 小时前
JavaScript 中的 sort 排序问题
前端·javascript
eason_fan2 小时前
Service Worker 缓存请求:前端性能优化的进阶利器
前端·性能优化
光影少年2 小时前
rn如何和原生进行通信,是单线程还是多线程,通信方式都有哪些
前端·react native·react.js·taro
好大哥呀3 小时前
Java Web的学习路径
java·前端·学习