相关文章推荐
玩足球的手套  ·  【java多线程】1 ...·  10 月前    · 
爱吹牛的烤红薯  ·  android yuv420渲染 ...·  1 年前    · 
爱笑的登山鞋  ·  java - Failed ...·  1 年前    · 

在后台管理系统,前台列表展示,时不时会碰到需要进行全选,反选操作,然后进行批量操作逻辑,最常见的要属后台的列表,以及前台需要做购物车的时候批量结算,或者阅读图书批量删除书签,笔记等等操作。本质上,都是表格结合checkbook进行的批量操作,学会一种,业务中基本上所有的这种批量选中操作思路基本都一样。

使用场景示例

App.vue

<template>
  <div id="app">
      <edit-table
        :tableDta="tableDta"
        :headData="headData"
        :allSelectTip="allSelectTip"
        :selectChange="handleSelectChange"
        :showEdit="showEdit"
      ></edit-table>
    </div>
  </div>
</template>
<script>
import EditTable from "./components/EditTable/EditTable.vue";
export default {
  name: "App",
  components: {
    EditTable,
  data() {
    return {
    //表格数据
      tableDta: [
          id: 1,
          chinase: 123,
          math: 111,
          english: 98,
          chemistry: 56,
          id: 2,
          chinase: 100,
          math: 99,
          english: 123,
          chemistry: 88,
          id: 3,
          chinase: 134,
          math: 34,
          english: 98,
          chemistry: 76,
          id: 4,
          chinase: 56,
          math: 22,
          english: 123,
          chemistry: 111,
      //表头全选,反选,提示文字
      allSelectTip: {
        confirm: "全部选中",
        cancel: "取消全选",
      //表头不数据
      headData: [
          id: 1,
          title: "语文",
          id: 2,
          title: "数学",
          id: 3,
          title: "英语",
          id: 4,
          title: "化学",
          id: 5,
          title: "操作",
      //是否显示checkbox
      showEdit: true,
  methods: {
    handleSelectChange(list) {
      console.log(list);
</script>

.components/EditTable/EditTable.vue

<template>
  <div class="edit-table">
    <!-- 表格数据 -->
    <table>
      <!-- 表头部分 -->
      <thead>
          <th v-if="showEdit">
          <!-- 表头checkbox组件:选中项的长度和表格数据长度一致的时候,表示全部全部选中 -->
            <check-box
              :text="checkBoxText"
              @change="handleAllChange"
              :checked="checkData.length == originData.length"
            ></check-box>
          <th v-for="item in headData" :key="item.id">{{ item.title }}</th>
      </thead>
      <!-- 表格主体部分 -->
      <tbody>
        <tr v-for="item in originData" :key="item.id">
          <!-- 表格主体checkbox组件:当前列在选中项中说明选中了.反之没有 -->
          <td v-show="showEdit">
            <check-box
              :checked="checkData.some((data) => data.id == item.id)"
              @change="(checked) => handleItemChange(checked, item)"
            ></check-box>
          <td v-for="subject in fieldList" :key="subject">
            {{ item[subject] }}
          <!-- 删除当前列 -->
          <td><button @click="handleDel(item)">删除</button></td>
      </tbody>
    </table>
    <!-- 批量操作 -->
    <div class="operate-group">
      <button @click="handleBatchOperate('all')">全选</button>
      <button @click="handleBatchOperate('cancel')">取消</button>
      <button @click="handleBatchOperate('del')">删除</button>
    </div>
  </div>
</template>
<script>
// checkbox组件
import CheckBox from "./CheckBox";
export default {
  components: {
    CheckBox,
  props: {
    // 表格数据
    tableDta: {
      type: Array,
      default() {
        return [];
    // 表头
    headData: {
      type: Array,
      default() {
        return [];
    // 权限,反选文字
    allSelectTip: {
      type: Object,
      default() {
        return {};
    // 选中项变化需要执行的函数
    selectChange: {
      type: Function,
      default() {
        return () => {};
    // 是否需要显示第一列checkbox
    showEdit: {
      type: Boolean,
      default: false,
  data() {
    return {
      // 保存选中项
      checkData: [],
      // 备份表格数据项
      originData: this.tableDta,
  computed: {
    // 动态计算全选,反选文字
    checkBoxText() {
      return this.checkData.length == this.originData.length
        ? this.allSelectTip.confirm
        : this.allSelectTip.cancel;
     * @Description 表格需要渲染的字段
     *   {
          id: 1,
          chinase: 123,
          math: 111,
          english: 98,
          chemistry: 56,
        我们需要排除id字段,id字段仅仅做key标识,不需要渲染到列表当中
    fieldList() {
      return this.tableDta.length
        ? Object.keys(this.tableDta[0]).filter((item) => item != "id")
        : [];
  methods: {
    //点列checkbox点击
    handleItemChange(checked, data) {
      if (checked) {
        // checkbox为true的时候,表示添加
        this.checkData = [...this.checkData, data];
      } else {
        // checkbox为true的时候,表示删除
        this.checkData = this.checkData.filter((item) => item.id != data.id);
      // 执行用户传进来的监听选中项变化的函数
      this.selectChange(this.checkData);
    // 所有checkbox点击
    handleAllChange(checked) {
      checked ? (this.checkData = [...this.originData]) : (this.checkData = []);
      // 执行用户传进来的监听选中项变化的函数
      this.selectChange(this.checkData);
    // 删除单个
    handleDel(data) {
      // 过滤掉当前项
      this.originData = this.originData.filter((item) => data.id != item.id);
      // 同步选中项
      this.checkData = this.checkData.filter((item) => data.id != item.id);
    // 批量删除
    batchDel() {
      // 循环选中项,执行过滤操作
      this.checkData.forEach((item) => {
        this.handleDel(item);
    // 批量操作
    handleBatchOperate(type) {
      switch (type) {
        case "all":
          this.handleAllChange(true);
          break;
        case "cancel":
          this.handleAllChange(false);
          break;
        case "del":
          this.batchDel();
          break;
</script>
<style lang="less">
.edit-table {
  table {
    width: 500px;
    border-collapse: collapse;
    text-align: center;
  table,
    border: 1px solid #ccc;
  .operate-group {
</style>

.components/EditTable/CheckBox.vue

<template>
    <input
      type="checkbox"
      :checked="checked"
      @change="$emit('change', $event.target.checked)"
    {{ text }}
  </div>
</template>
<script>
export default {
  props: {
    checked: Boolean,
    text: {
      type: String,
      default: "",
</script>
<style lang="less"></style>

掌握上面表格的基本思路之后,如果你项目里面有类似的全选,反选,操作,都可以套用这种写法,思路基本上都是类似的,剩下的可以自己扩展。

  • 私信