本文将使用 Vue 和 Element UI 封装一个通用的增删改查组件,这个组件可以用来操作任何类型的数据,包括但不限于表格数据、列表数据、树形结构数据等等。下面是一个基本的思路和代码示例。

1. 定义组件的基本结构和属性

包括数据源、分页信息、搜索条件、操作按钮等等。

<template>
  <div>
    <el-form :inline="true">
      <el-form-item label="关键词">
        <el-input v-model="keyword" placeholder="请输入关键词"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="search">查询</el-button>
        <el-button type="primary" @click="add">新增</el-button>
      </el-form-item>
    </el-form>
    <el-table :data="tableData">
      <el-table-column v-for="col in columns" :key="col.prop" :prop="col.prop" :label="col.label"></el-table-column>
      <el-table-column fixed="right" label="操作" width="200">
        <template slot-scope="scope">
          <el-button @click="edit(scope.row)">编辑</el-button>
          <el-button type="danger" @click="del(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination :total="total" :page-size="pageSize" :current-page.sync="currentPage" @current-change="pageChange"></el-pagination>
  </div>
</template>

<script>
export default {
  name: 'CrudTable',
  props: {
    api: {
      type: String,
      required: true,
      default: ''
    },
    columns: {
      type: Array,
      required: true,
      default: () => []
    }
  },
  data() {
    return {
      tableData: [],
      total: 0,
      pageSize: 10,
      currentPage: 1,
      keyword: ''
    }
  },
  methods: {
    search() {
      // TODO: 发送搜索请求
    },
    add() {
      // TODO: 打开新增对话框
    },
    edit(row) {
      // TODO: 打开编辑对话框
    },
    del(row) {
      // TODO: 发送删除请求
    },
    pageChange(page) {
      // TODO: 发送分页请求
    }
  }
}
</script>

2. 在 created 钩子中初始化数据

包括获取数据总数、获取第一页数据等等。

created() {
  this.getPageData(1)
},
methods: {
  async getPageData(page) {
    const res = await this.$axios.get(this.api, {
      params: {
        page,
        pageSize: this.pageSize,
        keyword: this.keyword
      }
    })
    this.tableData = res.data.items
    this.total = res.data.total
  }
  // ...
}

3. 实现各个方法的具体逻辑

包括发送搜索请求、打开新增/编辑对话框、发送删除请求、发送分页请求等等。

methods: {
  async search() {
    await this.getPageData(1)
  },
  async add() {
    // TODO: 打开新增对话框
  },
  async edit(row) {
    // TODO: 打开编辑对话框
  },
  async del(row) {
    const res = await this.$axios.delete(`${this.api}/${row.id}`)
    if (res.code === 0) {
      this.$message.success('删除成功')
      await this.getPageData(this.currentPage)
    } else {
      this.$message.error('删除失败')
    }
  },
  async pageChange(page) {
    await this.getPageData(page)
  }
}

4. 根据具体业务需求,扩展组件的功能

包括但不限于增加更多的操作按钮、增加搜索条件、支持树形结构数据等等。

<template>
  <div>
    <el-form :inline="true">
      <el-form-item label="关键词">
        <el-input v-model="keyword" placeholder="请输入关键词"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="search">查询</el-button>
        <el-button type="primary" @click="add">新增</el-button>
        <el-button type="primary" @click="import">导入</el-button>
        <el-button type="primary" @click="export">导出</el-button>
      </el-form-item>
    </el-form>
    <el-table :data="tableData">
      <el-table-column v-for="col in columns" :key="col.prop" :prop="col.prop" :label="col.label"></el-table-column>
      <el-table-column fixed="right" label="操作" width="200">
        <template slot-scope="scope">
          <el-button @click="edit(scope.row)">编辑</el-button>
          <el-button type="danger" @click="del(scope.row)">删除</el-button>
          <el-button v-if="scope.row.children" @click="expand(scope.row)">展开</el-button>
          <el-button v-else-if="scope.row.hasChildren" @click="collapse(scope.row)">收起</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination :total="total" :page-size="pageSize" :current-page.sync="currentPage" @current-change="pageChange"></el-pagination>
  </div>
</template>

<script>
export default {
  name: 'CrudTable',
  props: {
    api: {
      type: String,
      required: true,
      default: ''
    },
    columns: {
      type: Array,
      required: true,
      default: () => []
    },
    searchFields: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      tableData: [],
      total: 0,
      pageSize: 10,
      currentPage: 1,
      keyword: ''
    }
  },
  methods: {
    async search() {
      await this.getPageData(1)
    },
    async add() {
      // TODO: 打开新增对话框
    },
    async edit(row) {
      // TODO: 打开编辑对话框
    },
    async del(row) {
      const res = await this.$axios.delete(`${this.api}/${row.id}`)
      if (res.code === 0) {
        this.$message.success('删除成功')
        await this.getPageData(this.currentPage)
      } else {
        this.$message.error('删除失败')
      }
    },
    async pageChange(page) {
      await this.getPageData(page)
    },
    async expand(row) {
      // TODO: 展开子节点
    },
    async collapse(row) {
      // TODO: 收起子节点
    },
    async import() {
      // TODO: 导入数据
    },
    async export() {
      // TODO: 导出数据
    },
    async getPageData(page) {
      const params = {
        page,
        pageSize: this.pageSize,
        keyword: this.keyword
      }
      for (const field of this.searchFields) {
        params[field.prop] = field.value
      }
      const res = await this.$axios.get(this.api, { params })
      this.tableData = res.data.items
      this.total = res.data.total
    }
  }
}
</script>

这样,一个基本的增删改查组件就完成了。当然,具体的实现还需要根据具体业务需求进行调整和扩展,比如支持多种数据源、动态生成操作按钮等等。

Vue + Element UI 通用增删改查组件封装教程 - 代码示例

原文地址: https://www.cveoy.top/t/topic/lLqo 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录