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日

相关文章

  • rundll32.exe应用程序错误的解决方法

    当系统运行rundll32.exe文件时,有可能会出现应用程序错误的情况。可能的原因是rundll32.exe文件本身出现了问题,或是某些相关的库文件出现了损坏。针对这个问题,以下是解决方法的完整攻略: 步骤一:检查系统文件 在开始解决rundll32.exe应用程序错误之前,我们需要检查系统文件的完整性。我们可以使用Windows自带的SFC(System…

    other 2023年6月25日
    00
  • Android中Fragmen首选项使用自定义的ListPreference的方法

    下面是针对于“Android中Fragmen首选项使用自定义的ListPreference的方法”的完整攻略,并且给出两个示例说明。 步骤1:新建一个自定义的ListPreference 在res/xml文件夹下创建一个名为preferences.xml的xml文件,用于存放自定义的ListPreference。 在preferences.xml文件中添加以…

    other 2023年6月26日
    00
  • jenkins部署分支报finished:unstable的问题解决

    当然,我可以为您提供有关“Jenkins部署分支报finished:unstable的问题解决”的完整攻略,以下是详细说明: 问题描述 在使用Jenkins分支部署时,可能会遇到“finished:unstable”状态的问题。这种情况通常表示构建过程中出现了一些问题,但构建仍然完成了。这可能会导致部署失败或出现其他问题。 问题解决 以下是解决Jenkins…

    other 2023年5月7日
    00
  • Go语言中map使用和并发安全详解

    Go语言中map使用和并发安全详解 概述 在Go语言中,map是一种集合类型,它可以关联一个键和一个值。map是一种引用类型,可以使用 make 函数来创建。map 的底层实现是 hash 表,因此 map 的键是无序的,但是在迭代过程中,Go语言会自动对其进行排序。 map 的基本使用方法是:使用键访问值,如果键不存在,则会返回初始值。map 与 slic…

    other 2023年6月26日
    00
  • 侠盗猎车手5无法连接到网络怎么办 解决方法详解

    侠盗猎车手5无法连接网络的解决方法 问题描述 在游玩侠盗猎车手5的过程中,有些玩家可能会遭遇到无法连接到网络的问题,这个问题可能会导致玩家无法与其他玩家一起游戏,影响游戏体验。所以我们需要找到有效的解决方法,下面提供两种可行的解决方案。 方案一:检查网络连通性 首先我们需要检查我们的网络设置,确保我们的网络连接正常。操作步骤如下: 打开系统的“网络和共享中心…

    other 2023年6月27日
    00
  • iOS多线程介绍

    下面我将详细地讲解“iOS多线程介绍”的完整攻略。 iOS多线程介绍 在iOS开发中,多线程机制可以提高应用程序的性能和响应速度。iOS中主要有两种多线程编程方式:GCD和NSOperation。在使用多线程编程时,我们需要了解多线程的概念、多线程的使用场景、多线程的优缺点、多线程的线程间通信等问题,下面将一一讲解。 什么是多线程? 多线程指的是在一个进程中…

    other 2023年6月27日
    00
  • 金立S5.5开发者选项在什么位置?金立S5.5打开usb调试方法 如何打开USB调试?

    金立S5.5是一款移动设备,如果需要进行调试或者开发,需要开启开发者选项和USB调试。以下是详细的攻略: 1.开启开发者选项 开启开发者选项步骤: 打开设备的“设置”应用程序。 滑动屏幕并找到“关于手机”或“关于平板电脑”选项,点击进入。 在“关于手机”或“关于平板电脑”菜单中,查找“版本号”选项,多次点击版本号选项,系统将提示“您现在进入开发者模式”。 打…

    other 2023年6月26日
    00
  • 举例解析Java的设计模式编程中里氏替换原则的意义

    举例解析Java的设计模式编程中里氏替换原则的意义 什么是里氏替换原则? 里氏替换原则是面向对象设计原则中的一种,该原则的定义为: 如果一个软件实体使用一个父类的对象,那么它可以替换为一个子类的对象,而不会影响程序的正确性。简单来说,就是将子类对象当成父类对象使用时,程序不会出错。 里氏替换原则的意义 理解里氏替换原则的一个重要意义是能够写出优秀的、可维护的…

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