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

相关推荐
Java陈序员6 小时前
太香了!一款轻量级的 Elasticsearch 可视化管理工具!
vue.js·elasticsearch·vite
万物得其道者成8 小时前
前端大整数精度丢失:一次踩坑后的实战解决方案(`json-bigint`)
前端·json
鹏北海8 小时前
移动端 H5 响应式字体适配方案完全指南
前端
姜太公钓鲸2339 小时前
ROM就是程序存储器,实际的存储介质是Flash闪存。上述描述中的程序存储器是什么意思?
开发语言·javascript·ecmascript
柳杉10 小时前
使用AI从零打造炫酷医疗数据可视化大屏,源码免费拿!
前端·javascript·数据可视化
凌云拓界10 小时前
前端开发的“平衡木”:在取舍之间找到最优解
前端·性能优化·架构·前端框架·代码规范·设计规范
zhengfei61111 小时前
【XSS payload 】一个经典的XSS payload
前端·xss
简单Janeee11 小时前
[Vue 3 从零到上线]-第四篇:组件化思维——把网页像积木一样拆解
javascript·vue.js·ecmascript
全栈老石12 小时前
手写一个无限画布 #1:坐标系的谎言
前端·canvas
XW010599912 小时前
4-11判断素数
前端·python·算法·素数