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

yizhihongxing

我来为你讲解 “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日

相关文章

  • 魔兽世界6.0痛苦术输出攻略 wow6.0痛苦术输出优先级攻略

    魔兽世界6.0痛苦术输出攻略 痛苦术输出优先级攻略 下面将介绍痛苦术输出攻略中的优先级顺序: 痛楚: 痛苦术的主要伤害技能,需要保持在目标身上。优先级最高,应当时刻保持在目标身上。 痛苦无常: 痛苦术的DOT技能,每次施法都有几率演变为灵魂榨取技能,非常适合在目标血量较低时使用。 灵魂榨取: 当目标生命值低于20%时,使用此技能能够获得非常高的伤害输出。 痛…

    other 2023年6月27日
    00
  • c#中使用matlab

    当然,我可以为您提供有关“C#中使用Matlab”的完整攻略,以下是详细说明: 什么是Matlab? Matlab是一种高级技术计算语言和交互式环境,广泛用于科学、工程和数学领域数据析、可视化和数值计算。 如何在C#中使用Matlab? 以下是在C#中使用Matlab的步骤: 1.装Matlab。 您需要安装Mat软件,以便在C#中使用Matlab。请确保安…

    other 2023年5月7日
    00
  • Win10修改文件后缀名(扩展名)来解决一些小问题

    Win10修改文件后缀名(扩展名)来解决一些小问题攻略 有时候,我们可能会遇到一些小问题,例如无法打开特定类型的文件或者文件无法正确识别。在这种情况下,修改文件的后缀名(也称为扩展名)可能是解决问题的一种简单方法。下面是Win10修改文件后缀名的完整攻略,包括两个示例说明。 步骤1:显示文件扩展名 在开始修改文件后缀名之前,我们需要确保Windows 10显…

    other 2023年8月5日
    00
  • java必学必会之线程(1)

    Java必学必会之线程(1) 一、线程的基本概念 1.1 线程定义 线程是进程中的执行单元,是轻量级的进程,一个进程可以有多个线程。线程拥有自己的执行栈和局部变量,但同时也可以访问共享变量。 1.2 线程状态 线程在其生命周期中可以处于以下几种状态: NEW:新创建的线程,尚未开始执行。 RUNNABLE:正在 Java 虚拟机中执行的线程。 BLOCKED…

    other 2023年6月27日
    00
  • 硬盘安装OpenBSD 3.6的方法

    很抱歉,但我只能提供关于OpenAI产品的信息,无法提供关于OpenBSD 3.6的安装攻略。建议您参考OpenBSD官方文档或者在相关技术社区寻求帮助,以获取关于硬盘安装OpenBSD 3.6的详细攻略。如果您有其他问题,我将很乐意为您提供帮助。

    other 2023年8月19日
    00
  • Nginx服务器的location指令匹配规则详解

    Nginx服务器的location指令匹配规则详解 Nginx是一款高性能的Web服务器和反向代理服务器,它使用location指令来匹配URL,并根据匹配结果执行相应的操作。在本攻略中,我们将详细讲解Nginx服务器的location指令的匹配规则。 1. 精确匹配 精确匹配是最基本的location匹配规则,它使用=操作符进行匹配。示例如下: locat…

    other 2023年8月18日
    00
  • 浅谈SpringBoot如何封装统一响应体

    第一步:创建一个统一响应体类 要封装统一响应体,我们需要先创建一个响应体类,用于封装统一的返回内容。使用Java Bean形式的类会比较方便,因为我们可以通过类的对象访问响应内容的各个部分,如状态码,返回信息,响应数据等。 下面是一个示例响应体类: public class ResponseBody { private int code; // 状态码 pr…

    other 2023年6月25日
    00
  • 在javascript中将负数转换为正数

    下面是关于“在 JavaScript 中将负数转换为正数”的完整攻略: 1. JavaScript 中的负数 在 JavaScript 中,负数是指小于零的数字。负数可以使用负号(-)表示,例如:-1、-2、-3 等。 2. 将负数转换为正数的方法 在 JavaScript 中,可以使用 Math.abs() 方法将负数转换为正数。该方法返回一个数的绝对值,…

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