vue.js管理后台table组件封装的方法

我来为你讲解 “Vue.js管理后台table组件封装的方法”的完整攻略。

一、背景介绍

在管理后台开发中,表格展示是必不可少的控件,但是我们往往还需要对表格做各种处理,例如支持多选、排序等等,因此将表格进行封装,可以提高开发效率,简化代码复杂度。

二、封装思路

我们将 Table 的一些常用功能进行封装,例如:

  • 支持多选/单选
  • 支持数据的增删改查操作
  • 支持行样式/列样式的自定义
  • 支持排序/筛选功能

具体实现方法有很多,下面我将提供一种比较常见的封装思路。

1. 创建基础 Table 组件

首先,我们需要创建一个基础的 Table 组件,包含了最基本的展示数据功能。在组件中,我们可以通过 props 的方式传入表格的列数据和行数据,然后通过 v-for 指令进行渲染。

<template>
  <table>
    <thead>
      <tr>
        <th v-for="column in columns" :key="column.field">{{ column.label }}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in rows" :key="index">
        <td v-for="column in columns" :key="column.field">{{row[column.field]}}</td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    rows: {
      type: Array,
      default: () => []
    }
  }
}
</script>

2. 增加多选/单选功能

为了支持多选/单选功能,我们需要添加一个复选框,以及对应的选中状态。我们可以在组件的 data 中添加一个 selectedRows 属性,用于存储当前选中的行数据。然后在表格中添加一个选择列,通过 v-model 双向绑定实现选择状态的控制。

<template>
  <table>
    <thead>
      <tr>
        <th>
          <input type="checkbox"
            v-model="allSelected"
            @change="selectAll($event)"/>
        </th>
        <th v-for="column in columns" :key="column.field">{{ column.label }}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in rows" :key="index">
        <td>
          <input type="checkbox"
            v-model="selectedRows"
            :value="row"/>
        </td>
        <td v-for="column in columns" :key="column.field">{{row[column.field]}}</td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    rows: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      allSelected: false,
      selectedRows: []
    }
  },
  methods: {
    selectAll(event) {
      this.selectedRows = event.target.checked ? this.rows : []
    }
  }
}
</script>

3. 增加数据的增删改查功能

为了支持数据的增删改查功能,我们需要在 Table 组件中添加一些按钮,用于操作数据。例如,添加按钮、编辑按钮、删除按钮等等。然后我们可以提取一个 Dialog 组件,用于添加和编辑数据,并使用 slot 的方式将表单内容传入,相当于将弹窗的内容进行了封装。在 Dialog 中,我们可以通过 $emit 方式触发表格的 update 和 create 事件,数据更新后再更新表格即可。

<template>
  <div>
    <button @click="create">添加</button>
    <table>
      <!-- 表头 -->
      <thead>
        <tr>
          <th>
            <input type="checkbox"
              v-model="allSelected"
              @change="selectAll($event)"/>
          </th>
          <th v-for="column in columns" :key="column.field">{{ column.label }}</th>
          <th>操作</th>
        </tr>
      </thead>
      <!-- 数据 -->
      <tbody>
        <tr v-for="(row, index) in rows" :key="index">
          <td>
            <input type="checkbox"
              v-model="selectedRows"
              :value="row"/>
          </td>
          <td v-for="column in columns" :key="column.field">{{row[column.field]}}</td>
          <td>
            <button @click="edit(row)">编辑</button>
            <button @click="remove(row)">删除</button>
          </td>
        </tr>
      </tbody>
    </table>
    <Dialog v-model="dialogVisible"
      @update="update"
      @create="create">
      <!-- 插槽,用于传递弹窗中的表单数据 -->
      <slot name="form"></slot>
    </Dialog>
  </div>
</template>

<script>
import Dialog from '@/components/Dialog.vue'

export default {
  components: {
    Dialog
  },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    rows: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      allSelected: false,
      selectedRows: [],
      dialogVisible: false,
      currentRow: {}
    }
  },
  methods: {
    create() {
      this.currentRow = {}
      this.dialogVisible = true
    },
    update(row) {
      // 更新数据
      this.rows = this.rows.map(item => item.id === row.id ? row : item)
    },
    remove(row) {
      // 删除数据
      this.rows = this.rows.filter(item => item.id !== row.id)
    },
    selectAll(event) {
      this.selectedRows = event.target.checked ? this.rows : []
    },
    edit(row) {
      // 编辑数据
      this.currentRow = {...row}
      this.dialogVisible = true
    }
  }
}
</script>

4. 增加样式的自定义

为了支持样式的自定义,我们可以在 Table 中定义 slot,用于传入行样式和列样式。例如,我们可以在 tr 中添加一个 row-class 的属性,用于设置行的样式名,然后在表格中添加一个名为 row 的 slot,并根据传递的 row 数据设置样式。列样式的自定义也类似。

<template>
  <table>
    <!-- 表头 -->
    <thead>
      <tr>
        <th>
          <input type="checkbox"
            v-model="allSelected"
            @change="selectAll($event)"/>
        </th>
        <th v-for="column in columns" :key="column.field">{{ column.label }}</th>
        <th>操作</th>
      </tr>
    </thead>
    <!-- 数据 -->
    <tbody>
      <tr v-for="(row, index) in rows" :key="index"
        :class="getRowClass(row)">
        <td>
          <input type="checkbox"
            v-model="selectedRows"
            :value="row"/>
        </td>
        <td v-for="column in columns" :key="column.field"
          :class="getColumnClass(row, column.field)">{{row[column.field]}}</td>
        <td>
          <button @click="edit(row)">编辑</button>
          <button @click="remove(row)">删除</button>
        </td>
      </tr>
    </tbody>
    <!-- 插槽,用于传递行样式和列样式 -->
    <slot name="row" :row="rows"></slot>
    <slot name="column"></slot>
  </table>
</template>

<script>
import Dialog from '@/components/Dialog.vue'

export default {
  components: {
    Dialog
  },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    rows: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      allSelected: false,
      selectedRows: [],
      dialogVisible: false,
      currentRow: {}
    }
  },
  methods: {
    create() {
      this.currentRow = {}
      this.dialogVisible = true
    },
    update(row) {
      // 更新数据
      this.rows = this.rows.map(item => item.id === row.id ? row : item)
    },
    remove(row) {
      // 删除数据
      this.rows = this.rows.filter(item => item.id !== row.id)
    },
    selectAll(event) {
      this.selectedRows = event.target.checked ? this.rows : []
    },
    edit(row) {
      // 编辑数据
      this.currentRow = {...row}
      this.dialogVisible = true
    },
    // 获取行样式,在插槽中使用
    getRowClass(row) {
      // todo: 实现根据不同的条件返回不同的 class 名称
      return 'row-class'
    },
    // 获取列样式,在插槽中使用
    getColumnClass(row, field) {
      // todo: 实现根据不同的条件返回不同的 class 名称
      return 'column-class'
    }
  }
}
</script>

5. 增加排序/筛选功能

为了支持排序/筛选功能,我们可以在表头的列上添加一个排序/筛选图标,然后监听点击事件,通过排序/筛选算法对数据进行操作即可。例如,我们可以在 Table 中定义一个 sortField 和 sortType 属性,用于存储当前的排序字段和排序类型,然后在点击表头列时根据当前的排序状态修改 sortField 和 sortType,最后使用 Array.sort 方法对数据进行排序。

<template>
  <table>
    <!-- 表头 -->
    <thead>
      <tr>
        <th>
          <input type="checkbox"
            v-model="allSelected"
            @change="selectAll($event)"/>
        </th>
        <th v-for="column in columns" :key="column.field"
          @click="handleSort(column.field)">
          {{ column.label }}
          <span class="sort-icon"
            :class="{
              'sort-asc': sortField === column.field && sortType === 'asc',
              'sort-desc': sortField === column.field && sortType === 'desc'
            }"></span>
        </th>
        <th>操作</th>
      </tr>
    </thead>
    <!-- 数据 -->
    <tbody>
      <tr v-for="(row, index) in rows" :key="index"
        :class="getRowClass(row)">
        <td>
          <input type="checkbox"
            v-model="selectedRows"
            :value="row"/>
        </td>
        <td v-for="column in columns" :key="column.field"
          :class="getColumnClass(row, column.field)">{{row[column.field]}}</td>
        <td>
          <button @click="edit(row)">编辑</button>
          <button @click="remove(row)">删除</button>
        </td>
      </tr>
    </tbody>
    <!-- 插槽,用于传递行样式和列样式 -->
    <slot name="row" :row="rows"></slot>
    <slot name="column"></slot>
  </table>
</template>

<script>
import Dialog from '@/components/Dialog.vue'

export default {
  components: {
    Dialog
  },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    rows: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      allSelected: false,
      selectedRows: [],
      dialogVisible: false,
      currentRow: {},
      sortField: '',
      sortType: ''
    }
  },
  methods: {
    create() {
      this.currentRow = {}
      this.dialogVisible = true
    },
    update(row) {
      // 更新数据
      this.rows = this.rows.map(item => item.id === row.id ? row : item)
    },
    remove(row) {
      // 删除数据
      this.rows = this.rows.filter(item => item.id !== row.id)
    },
    selectAll(event) {
      this.selectedRows = event.target.checked ? this.rows : []
    },
    edit(row) {
      // 编辑数据
      this.currentRow = {...row}
      this.dialogVisible = true
    },
    // 获取行样式,在插槽中使用
    getRowClass(row) {
      // todo: 实现根据不同的条件返回不同的 class 名称
      return 'row-class'
    },
    // 获取列样式,在插槽中使用
    getColumnClass(row, field) {
      // todo: 实现根据不同的条件返回不同的 class 名称
      return 'column-class'
    },
    // 排序
    sort() {
      // 从小到大排序
      if (this.sortType === 'asc') {
        this.rows.sort((a, b) => a[this.sortField] - b[this.sortField])
      }
      // 从大到小排序
      if (this.sortType === 'desc') {
        this.rows.sort((a, b) => b[this.sortField] - a[this.sortField])
      }
    },
    // 点击表头排序
    handleSort(field) {
      // 默认为从小到大排序
      let type = 'asc'
      // 如果当前点击的就是排序的列,那么将排序类型翻转
      if (this.sortField === field) {
        type = this.sortType === 'asc' ? 'desc' : 'asc'
      }
      // 更新排序状态
      this.sortField = field
      this.sortType = type
      // 对数据进行重新排序
      this.sort()
    }
  }
}
</script>

三、总结

以上就是 Vue.js 管理后台 Table 组件的封装方法。通过封装 Table 组件,我们可以提高开发效率,优化代码结构,降低维护成本。当然,以上示例中的实现方式还有很多需要改进的地方,可以根据需求进行相应的调整和改动。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue.js管理后台table组件封装的方法 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • Web移动端Fixed布局的解决方案

    Web移动端Fixed布局主要是为了在移动端上实现固定定位,使得页面元素固定在页面指定位置不会跟随页面滚动而发生变化。但是,在某些情况下,Fixed布局会给开发和设计带来很大的困扰,如在iOS上Fixed布局时,可能会出现滑动空白区域无法回到原来Fixed定位的位置的问题,这就需要我们在开发时寻找一种更加灵活的解决方案。下面是Web移动端Fixed布局解决方…

    other 2023年6月26日
    00
  • GDAL 矢量属性数据修改方式(python)

    一、GDAL简介 GDAL是Geospatial Data Abstraction Library的缩写,是一个开源的、独立的数据转换库,支持多种空间数据格式的读写、投影变换和简单的数据编辑操作。GDAL不仅支持矢量数据格式,还支持栅格数据格式。它能读取的格式,如下表: 格式 读写 备注 ESRI Shapefile 部分支持 仅支持点、线和面要素 GeoJ…

    other 2023年6月25日
    00
  • Go语言字符串常见操作的使用汇总

    Go语言字符串常见操作的使用汇总 字符串基础 字符串是由一系列字符组成的,一般用来表示文本的信息。 在Go语言中,字符串属于基础数据类型,使用双引号”或反引号`来定义。其基础定义如下: // 使用双引号定义 str1 := "Hello, world!" // 使用反引号定义 str2 := `Hello, world!` 字符串常见操作…

    other 2023年6月20日
    00
  • python3 读取文件跳过文件第一行内容

    下面是“python3 读取文件跳过文件第一行内容的完整攻略”的详细讲解,包括读取文件的基本概念、两种实现方法、示例说明等方面。 读取文件的基本概念 在Python中,可以使用open函数来打开一个文件,并使用read方法来读取文件的内容。但是,在读取文件时,有时需要跳过文件的第一行内容,例如读取CSV文件时,第一行通常是表头,需要跳过。 两种实现方法 在P…

    other 2023年5月5日
    00
  • windows 文件名太长怎么办?Windows关闭/开启短文件名功能的教程

    当Windows文件名太长时,会导致一些操作无法完成。这时可以尝试开启短文件名功能或者缩短文件名来解决问题。下面将详细介绍这两种解决方法。 问题原因及现象 当Windows文件名超过260个字符时,有些操作会因文件名太长而出现问题。出现这种情况的原因通常是由于文件夹目录结构复杂或文件名过长。 解决方法 解决这个问题的方法有两个: 开启短文件名功能 缩短文件名…

    other 2023年6月26日
    00
  • Alienware 13 R3值得买吗?Alienware 13 R3游戏本深度图解评测

    很抱歉,作为文本模型,我无法以标准的markdown格式回答您的问题。但是,我可以为您提供一份详细的攻略,包含Alienware 13 R3游戏本的深度图解评测。以下是攻略的大致内容: Alienware 13 R3游戏本深度图解评测 外观设计:Alienware 13 R3采用了独特的外观设计,具有科幻感和高端感。机身采用铝合金材质,坚固耐用。键盘背光灯效…

    other 2023年10月17日
    00
  • ecshop数据库操作类

    ECShop是一款流行的开源电子商务平台,它使用MySQL数据库来存储数据。在ECShop中,我们可以使用数据库操作类来执行各种数据库操作,例如插入、更新、删除和查询数据。在本文中,我们将讨论如何使用ECShop数据库操作类,包括连接到数据库、执行SQL查询和更新操作等。 连接到数据库 要连接到ECShop数据库,请使用以下代码: require_once(…

    other 2023年5月5日
    00
  • 分享面试官常用16个c/c++面试题

    分享面试官常用16个C/C++面试题攻略 在C/C++面试中,经常会涉及一些基本的数据结构、算法、指针等等的基本原理。下面是面试官常用的16个C/C++面试题,介绍一下如何准备和应对这些问题。 1. 什么是指针? 指针是一个特殊的变量,它可以保存变量的地址,从而让程序员操作内存中的数据。 2. 指针和数组有什么关系? 指针和数组非常类似,实际上数组名就是一个…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部