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

相关推荐
前端小L41 分钟前
双指针专题(三):去重的艺术——「三数之和」
javascript·算法·双指针与滑动窗口
0和1的舞者41 分钟前
Spring AOP详解(一)
java·开发语言·前端·spring·aop·面向切面
web小白成长日记1 小时前
在Vue样式中使用JavaScript 变量(CSS 变量注入)
前端·javascript·css·vue.js
QT 小鲜肉1 小时前
【Linux命令大全】001.文件管理之which命令(实操篇)
linux·运维·服务器·前端·chrome·笔记
C_心欲无痕1 小时前
react - useImperativeHandle让子组件“暴露方法”给父组件调用
前端·javascript·react.js
霖鸣2 小时前
Minecraft通过kubejs进行简单魔改
javascript
JackieDYH2 小时前
HTML+CSS+JavaScript实现图像对比滑块demo
javascript·css·html
BullSmall3 小时前
支持离线配置修改及删除操作的实现方案
前端
全栈前端老曹3 小时前
【前端路由】Vue Router 嵌套路由 - 配置父子级路由、命名视图、动态路径匹配
前端·javascript·vue.js·node.js·ecmascript·vue-router·前端路由
EndingCoder4 小时前
安装和设置 TypeScript 开发环境
前端·javascript·typescript