【sgTransfer】自定义组件:带有翻页、页码、分页器的穿梭框组件,支持大批量数据的穿梭显示。

这篇具有很好参考价值的文章主要介绍了【sgTransfer】自定义组件:带有翻页、页码、分页器的穿梭框组件,支持大批量数据的穿梭显示。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 【sgTransfer】自定义组件:带有翻页、页码、分页器的穿梭框组件,支持大批量数据的穿梭显示。,Vue.js,vue.js,elementui,javascript

特性: 文章来源地址https://www.toymoban.com/news/detail-692945.html

  1. 表格宽度可以自定义
  2. 翻页器显示控件可以自定义
  3. 列配置项可以设置显示字段列名称、宽度、字段名
  4. 可以配置搜索框提示文本,支持搜索过滤
  5. 穿梭框顶部标题可以自定义
  6. 左右箭头按钮文本可以设置

sgTransfer源码

<template>
  <div :class="$options.name">
    <div
      class="sg-start"
      :style="{ width: width, height: height, ...style, ...style_start }"
    >
      <div class="sg-title" v-if="titles">
        {{ titles[0] }}
      </div>
      <div class="sg-search">
        <el-input
          style="width: 100%"
          v-model.trim="inputSearchValue_start"
          maxlength="20"
          :show-word-limit="false"
          :placeholder="filterPlaceholder || `请输入搜索内容...`"
          clearable
          @keyup.native.enter="initListStart"
          @clear="initListStart"
        >
          <el-button slot="append" icon="el-icon-search" @click="initListStart" />
        </el-input>
      </div>
      <div class="sg-table">
        <el-table
          ref="table_start"
          :data="tableData_start"
          :header-cell-style="{ background: '#f5f7fa' }"
          :height="height ? `calc(${height} - 150px)` : '300px'"
          style="width: 100%"
          stripe
          @selection-change="selection_start_change"
          :row-class-name="row_class_name"
          @row-click="row_click_start"
          @row-dblclick="row_dblclick_start"
        >
          <el-table-column type="selection" minWidth="50" :selectable="selectable" />
          <el-table-column
            v-for="(a, i) in tableItems_start"
            :key="i"
            :prop="a.prop"
            :label="a.label"
            :width="a.width || false"
            :minWidth="a.minWidth || false"
            show-overflow-tooltip
          />
        </el-table>
      </div>
      <div class="sg-pagination">
        <el-pagination
          background
          :hidden="startPage.total <= 10"
          :layout="layout"
          :page-sizes="[10, 20, 50]"
          :pager-count="5"
          :current-page.sync="startPage.currentPage"
          :page-size.sync="startPage.pageSize"
          :total="startPage.total"
          @size-change="pageChange"
          @current-change="pageChange"
        />
      </div>
    </div>
    <div class="sg-center">
      <el-button
        :disabled="disabledLeftButton"
        @click="remove"
        type="primary"
        icon="el-icon-arrow-left"
        >{{ buttonTexts ? buttonTexts[0] : "" }}</el-button
      >
      <el-button :disabled="disabledRightButton" @click="add" type="primary"
        >{{ buttonTexts ? buttonTexts[1] : ""
        }}<i class="el-icon-arrow-right" style="margin-left: 5px"></i
      ></el-button>
    </div>
    <div class="sg-end" :style="{ width: width, height: height, ...style, ...style_end }">
      <div class="sg-title" v-if="titles">
        {{ titles[1] }}
      </div>
      <div class="sg-search">
        <el-input
          style="width: 100%"
          v-model.trim="inputSearchValue_end"
          maxlength="20"
          :show-word-limit="false"
          :placeholder="filterPlaceholder || `请输入搜索内容...`"
          clearable
          @keyup.native.enter="initListEnd({ currentPage: 1 })"
          @clear="initListEnd"
        >
          <el-button
            slot="append"
            icon="el-icon-search"
            @click="initListEnd({ currentPage: 1 })"
          />
        </el-input>
      </div>
      <div class="sg-table">
        <el-table
          ref="table_end"
          :data="tableData_end"
          :header-cell-style="{ background: '#f5f7fa' }"
          :height="height ? `calc(${height} - 150px)` : '300px'"
          style="width: 100%"
          stripe
          @selection-change="selection_end_change"
          @row-click="row_click_end"
        >
          <el-table-column type="selection" minWidth="50" />
          <el-table-column
            v-for="(a, i) in tableItems_end"
            :key="i"
            :prop="a.prop"
            :label="a.label"
            :width="a.width || false"
            :minWidth="a.minWidth || false"
            show-overflow-tooltip
          />
        </el-table>
      </div>
      <div class="sg-pagination">
        <el-pagination
          background
          :hidden="endPage.total <= 10"
          :layout="layout"
          :page-sizes="[10, 20, 50]"
          :pager-count="5"
          :current-page.sync="endPage.currentPage"
          :page-size.sync="endPage.pageSize"
          :total="endPage.total"
          @size-change="initListEnd"
          @current-change="initListEnd"
        />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "sgTransfer",
  data() {
    return {
      width: "200px", //穿梭框宽度
      height: null, //穿梭框高度
      style: {}, //全局穿梭框样式
      style_start: {}, //左侧穿梭框样式
      style_end: {}, //右侧穿梭框样式
      layout: `total, sizes, prev, pager, next, jumper`,
      disabledForm: false,
      inputSearchValue_start: "",
      inputSearchValue_end: "",
      tableItems_start: [], //表格列配置项
      tableItems_end: [], //表格列配置项
      tableData_start: [], //呈现的当前页数据
      tableData_end: [], //呈现的当前页数据
      tableData_end_bk: [], //最终选择的数据
      selection_start: [],
      selection_end: [],
      startPage: { currentPage: 1, pageSize: 10, total: 0 },
      endPage: { currentPage: 1, pageSize: 10, total: 0 },
      mainKey: null, //主键
      filterKey_end: null, //右侧穿梭表过滤关键词字段
    };
  },
  props: [
    "value",
    "data",
    /*格式说明
         data: {
              width: '400px',//表格宽度
              layout: `total, sizes, prev, next, jumper`,//翻页器显示控件
              // 列配置项
              tableItems: [
              { prop: 'ID', label: '工号', minWidth: '50' },
              { prop: 'XM', label: '姓名', minWidth: '50' },
              { prop: 'YHM', label: '用户名', minWidth: '50' },
              ],
              tableData: [],//表格显示内容
              startPage: { total: 0, },//实际总数
        }, */
    "titles",
    "buttonTexts",
    "filterPlaceholder",
  ],
  computed: {
    disabledLeftButton(d) {
      return this.selection_end.length === 0;
    },
    disabledRightButton(d) {
      // 在左边表格选中项里面,遍历每一项,如果在右侧表格中都能找到匹配项就true
      return this.selection_start.every((row) =>
        this.tableData_end_bk.some((v) => this.isSameItem(v, row))
      );
    },
  },
  watch: {
    value: {
      handler(d) {
        // 避免重复循环执行双向绑定
        if (
          d &&
          JSON.stringify(JSON.parse(JSON.stringify(this.tableData_end_bk)).sort()) !==
            JSON.stringify(JSON.parse(JSON.stringify(d)).sort())
        ) {
          this.inputSearchValue_start = "";
          this.inputSearchValue_end = "";
          this.startPage.currentPage = 1;
          this.endPage.currentPage = 1;
          this.tableData_end_bk = d || [];
          this.initListStart();
        }
      },
      deep: true,
      immediate: true,
    },
    data: {
      handler(d) {
        if (d) {
          d.width && (this.width = d.width);
          d.height && (this.height = d.height);
          d.style && (this.style = d.style);
          d.style_start && (this.style_start = d.style_start);
          d.style_end && (this.style_end = d.style_end);
          d.layout && (this.layout = d.layout);
          this.tableData_start = d.tableData;
          this.tableItems_start = d.tableItems_start || d.tableItems;
          this.tableItems_end = d.tableItems_end || d.tableItems;
          this.mainKey = (this.tableItems_start.find((v) => v.mainKey) || {}).prop; //主键
          this.filterKey_end = (
            this.tableItems_start.find((v) => v.filterKey_end) || {}
          ).prop; //右侧穿梭表过滤关键词字段
          this.startPage.total = (d.startPage || {}).total || 0;
          this.$nextTick(() => {
            this.refreshCheckStatus();
          }); // 刷新勾选状态
        }
      },
      deep: true,
      immediate: true,
    },
    tableData_end_bk: {
      handler(d) {
        this.$emit(`input`, d);
        this.initListEnd();
      },
      deep: true,
      immediate: true,
    },
  },
  created() {
    let d = this.value;
    if (d && Object.keys(d).length) {
    } else this.initListStart();
  },
  methods: {
    // 双击选中移动到右侧
    row_dblclick_start(row, column, event) {
      this.$refs.table_start.toggleRowSelection(row, true);
      this.add();
    },
    row_click_start(row, column, event) {
      this.$refs.table_start.toggleRowSelection(row);
    },
    row_click_end(row, column, event) {
      this.$refs.table_end.toggleRowSelection(row);
    },
    pageChange(d) {
      this.initListStart();
    },
    // 刷新勾选状态
    refreshCheckStatus() {
      this.tableData_start.forEach((row) =>
        this.$refs.table_start.toggleRowSelection(
          row,
          this.tableData_end_bk.some((v) => this.isSameItem(v, row))
        )
      );
    },
    selectable(row) {
      return !this.tableData_end_bk.some((v) => this.isSameItem(v, row));
    },
    row_class_name({ row, rowIndex }) {
      return this.tableData_end_bk.find((v) => this.isSameItem(v, row)) ? "selected" : "";
    },
    isSameItem(a_obj, b_obj) {
      let isSame = true;
      if (this.mainKey) {
        isSame = a_obj[this.mainKey] == b_obj[this.mainKey];
      } else {
        isSame = Object.keys(a_obj).every((k) => a_obj[k] == b_obj[k]);
      }
      return isSame;
    },
    remove(d) {
      if (this.mainKey) {
        let selection_end_mainKeys = this.selection_end.map((v) => v[this.mainKey]);
        this.tableData_end_bk = this.tableData_end_bk.filter(
          (v) => !selection_end_mainKeys.includes(v[this.mainKey])
        );
      } else {
        let selection_end = this.selection_end.map((v) => JSON.stringify(v));
        this.tableData_end_bk = this.tableData_end_bk.filter(
          (v) => !selection_end.includes(JSON.stringify(v))
        );
      }
      this.$nextTick(() => {
        this.refreshCheckStatus();
      }); // 刷新勾选状态
    },
    add(d) {
      this.selection_start.forEach(
        (row) =>
          this.tableData_end_bk.some((v) => this.isSameItem(v, row)) ||
          this.tableData_end_bk.push(row)
      );
      this.$nextTick(() => {
        this.refreshCheckStatus();
      }); // 刷新勾选状态
    },
    selection_start_change(selection) {
      this.selection_start = selection;
    },
    selection_end_change(selection) {
      this.selection_end = selection;
    },
    initListStart() {
      this.$emit("init", {
        keyword: this.inputSearchValue_start,
        currentPage: this.startPage.currentPage || 1,
        pageSize: this.startPage.pageSize,
      });
    },
    initListEnd({
      keyword = this.inputSearchValue_end,
      currentPage = this.endPage.currentPage || 1,
      pageSize = this.endPage.pageSize,
    } = {}) {
      let maxPage = Math.ceil(this.tableData_end_bk.length / pageSize);
      currentPage > maxPage && (currentPage = maxPage);
      this.endPage.currentPage = currentPage;
      this.endPage.pageSize = pageSize;
      let results = [];
      if (this.filterKey_end) {
        results = this.tableData_end_bk.filter((obj) =>
          keyword
            ? (obj[this.filterKey_end] || "")
                .toString()
                .toLocaleLowerCase()
                .includes(keyword.toString().toLocaleLowerCase())
            : true
        );
      } else {
        results = this.tableData_end_bk.filter((obj) =>
          keyword
            ? Object.keys(obj).some((k) =>
                (obj[k] || "")
                  .toString()
                  .toLocaleLowerCase()
                  .includes(keyword.toString().toLocaleLowerCase())
              )
            : true
        );
      }
      this.endPage.total = results.length;
      this.tableData_end = results.slice(
        (currentPage - 1) * pageSize,
        currentPage * pageSize
      );
      if (this.tableData_end_bk.length) {
        this.tableData_end.length === 0 &&
          ((this.inputSearchValue_end = ""), this.initListEnd());
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.sgTransfer {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  white-space: nowrap;

  & > .sg-start,
  & > .sg-end {
    border: 1px solid #ebeef5;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
    display: inline-block;
    vertical-align: middle;
    max-height: 100%;
    box-sizing: border-box;
    position: relative;

    .sg-title {
      height: 40px;
      line-height: 40px;
      background: #f5f7fa;
      margin: 0;
      padding-left: 15px;
      border-bottom: 1px solid #ebeef5;
      box-sizing: border-box;
      color: #000;
    }

    .sg-search {
      box-sizing: border-box;
      padding: 10px;
    }

    .sg-table {
    }

    .sg-pagination {
      height: 50px;
      display: flex;
      justify-content: center;
      width: 100%;
      box-sizing: border-box;
      padding: 10px;
    }
  }

  & > .sg-center {
    margin: 0 10px;
  }

  & > .sg-end {
  }
}

>>> .el-table {
  tr.selected {
    filter: brightness(0.95);
    pointer-events: none;
  }

  .el-table__cell.gutter {
    border-bottom: 1px solid #ebeef5;
    background-color: #f5f7fa;
  }
}
</style>

用例

<template>
  <div>
    <sgTransfer
      v-model="transferValue"
      :data="transferData"
      :titles="['所有用户', '本组成员']"
      :button-texts="['到左边', '到右边']"
      :filter-placeholder="`请输入工号、姓名…`"
      @init="initTransfer"
    />

    <hr />

    <div>
      <h1>勾选的数据transferValue:</h1>
      <div
        v-html="JSON.stringify(transferValue).replace(/\,\{/g, ',\n{')"
        style="word-wrap: break-word; word-break: break-all; white-space: break-spaces"
      ></div>
    </div>
  </div>
</template>

<script>
import sgTransfer from "@/vue/components/admin/sgTransfer";

export default {
  components: { sgTransfer },
  data() {
    return {
      // 穿梭框配置项
      transferValue: [],
      transferData: {
        width: "400px", //表格宽度
        height: "calc(100vh - 200px)", //表格高度
        layout: `total, sizes, prev, next, jumper`, //翻页器显示控件
        // 列配置项
        tableItems: [
          { prop: "ID", label: "工号", minWidth: "50", mainKey: true }, //设置主键
          { prop: "XM", label: "姓名", minWidth: "50", filterKey_end: true  },//设置右侧穿梭表过滤关键词字段
          { prop: "YHM", label: "用户名", minWidth: "50" },
        ],
        tableData: [], //表格显示内容
        startPage: { total: 0 }, //实际总数
      },

      // 渲染数据
      tableData: [],
      tableData_bk: [],
      userList: [
        { key: 1, label: "梁冰露" },
        { key: 2, label: "吴梵听" },
        { key: 3, label: "卢令美" },
        { key: 4, label: "韩宛曼" },
        { key: 5, label: "郝海冬" },
        { key: 6, label: "傅优悦" },
        { key: 7, label: "郝幻莲" },
        { key: 8, label: "江嘉云" },
        { key: 9, label: "梁秋芳" },
        { key: 10, label: "郝悦颖" },
        { key: 11, label: "廖芝蓉" },
        { key: 12, label: "胡傲丝" },
        { key: 13, label: "赵珺琦" },
        { key: 14, label: "石心诺" },
        { key: 15, label: "丁翠芙" },
        { key: 16, label: "李夏河" },
        { key: 17, label: "范水悦" },
        { key: 18, label: "郑凝雪" },
        { key: 19, label: "李亦玉" },
        { key: 20, label: "袁三春" },
        { key: 21, label: "赵红叶" },
        { key: 22, label: "曹安琪" },
        { key: 23, label: "谭琴音" },
        { key: 24, label: "钟湛蓝" },
        { key: 25, label: "陆之柔" },
        { key: 26, label: "吕孒凡" },
        { key: 27, label: "熊野雪" },
        { key: 28, label: "曹叶澜" },
        { key: 29, label: "韩粟梅" },
        { key: 30, label: "孔杏儿" },
        { key: 31, label: "宋若彤" },
        { key: 32, label: "于淼淼" },
        { key: 33, label: "潘欣跃" },
        { key: 34, label: "石雅辰" },
        { key: 35, label: "白念珍" },
        { key: 36, label: "文爱茹" },
        { key: 37, label: "王如曼" },
        { key: 38, label: "宋丝琪" },
        { key: 39, label: "王凝荷" },
        { key: 40, label: "郑雨雪" },
        { key: 41, label: "梁映阳" },
        { key: 42, label: "徐新雨" },
        { key: 43, label: "毛恬雅" },
        { key: 44, label: "侯若蕊" },
        { key: 45, label: "杨云蔚" },
        { key: 46, label: "史之卉" },
        { key: 47, label: "胡千束" },
        { key: 48, label: "冯冷荷" },
        { key: 49, label: "金语心" },
        { key: 50, label: "江恬默" },
        { key: 51, label: "高香馨" },
        { key: 52, label: "江凌晴" },
        { key: 53, label: "梁列琴" },
        { key: 54, label: "邹鸾瑶" },
        { key: 55, label: "夏素洁" },
        { key: 56, label: "范秋玉" },
        { key: 57, label: "钟北嘉" },
        { key: 58, label: "谭水云" },
        { key: 59, label: "顾山柏" },
        { key: 60, label: "龙曼蔓" },
        { key: 61, label: "钟双儿" },
        { key: 62, label: "林林娜" },
        { key: 63, label: "邹溪儿" },
        { key: 64, label: "顾妙彤" },
        { key: 65, label: "傅茵茵" },
        { key: 66, label: "卢念露" },
        { key: 67, label: "罗冷亦" },
        { key: 68, label: "胡秋颖" },
        { key: 69, label: "姜怡月" },
        { key: 70, label: "傅和暄" },
        { key: 71, label: "赖布凡" },
        { key: 72, label: "郝念蕾" },
        { key: 73, label: "邱天欣" },
        { key: 74, label: "汤莉莉" },
        { key: 75, label: "段靖易" },
        { key: 76, label: "周之云" },
        { key: 77, label: "董映秋" },
        { key: 78, label: "汤玲琅" },
        { key: 79, label: "田雁梅" },
        { key: 80, label: "石雨雪" },
        { key: 81, label: "任君雅" },
        { key: 82, label: "蔡小谷" },
        { key: 83, label: "孟忆之" },
        { key: 84, label: "姜闲丽" },
        { key: 85, label: "文忆香" },
        { key: 86, label: "戴运虹" },
        { key: 87, label: "王玄穆" },
        { key: 88, label: "刘绿柳" },
        { key: 89, label: "萧梦丝" },
        { key: 90, label: "谭忆山" },
        { key: 91, label: "方榕嫣" },
        { key: 92, label: "徐欣合" },
        { key: 93, label: "夏雨南" },
        { key: 94, label: "尹沙羽" },
        { key: 95, label: "万梦玉" },
        { key: 96, label: "谢灵枫" },
        { key: 97, label: "曾源源" },
        { key: 98, label: "赖谷枫" },
        { key: 99, label: "彭子童" },
      ],
    };
  },
  created() {
    this.createTableData();
  },
  methods: {
    // 初始化、翻页、切换每页显示数量的时候触发
    initTransfer({ keyword = "", currentPage = 1, pageSize = 10 } = {}) {
      // 模拟接口调用----------------------------------------
      let results = this.tableData_bk.filter((obj) =>
        keyword
          ? Object.keys(obj).some((k) =>
              obj[k]
                .toString()
                .toLocaleLowerCase()
                .includes(keyword.toString().toLocaleLowerCase())
            )
          : true
      );
      this.transferData.startPage.total = results.length;
      this.transferData.tableData = results.slice(
        (currentPage - 1) * pageSize,
        currentPage * pageSize
      );
      // ----------------------------------------
    },
    // 构建数据
    createTableData(d) {
      this.tableData_bk = this.userList.map((v) => {
        let ID = this.$g.getRandomID();
        return { ID, XM: v.label, YHM: `user${ID}` };
      });
      this.initTransfer();
    },
  },
};
</script>

到了这里,关于【sgTransfer】自定义组件:带有翻页、页码、分页器的穿梭框组件,支持大批量数据的穿梭显示。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • DRF 分页器的使用

    drf提供了三个内置分页器,根据前端需求选择使用。 在配置文件中设置全局的分页方式,如: 也可通过继承内置的分页器类自定义Pagination类,来为视图添加不同分页器。在视图中通过 pagination_clas 属性来指明。 注意 :视图内局部设置不使用分页器 内置分页器的使用有两种

    2024年02月03日
    浏览(36)
  • Vue电商项目--分页器制作

    分页这个组件,不单单是一个页面用到了。多个页面同时用它,因此我们可以封装成一个全局组件 需要将这个分页结构拆分到components  通用的分页组件Pagination  然后全局的注册这个组件  有点小问题,改一下。让它上一页在1前面,和居中  这里要注意的一点就是这个newOrde

    2024年02月06日
    浏览(33)
  • Django_Paginator分页器

    目录 分页器代码说明 简单demo 源码等资料获取方法 执行结果如下: 定义视图 添加路由 添加demo.html模板 界面第5页展示如下:   各位想获取源码的朋友请点赞 + 评论 + 收藏 ,三连! 三连 之后我会在评论区挨个私信发给你们~

    2024年02月15日
    浏览(50)
  • elementui 分页器,el-pagination 不显示的问题

    今天敲代码遇到了个很操蛋的问题,我把分页器封装成共用组件,一个组件显示分页器,另一个组件不显示分页器,我心想这么邪门的吗,这个是正常组件 这个组件不显示 然后我尝试把传给分页器的参数打印出来, 果然发现了操蛋的地方,这是正常显示的数据 这是不显示的

    2024年02月12日
    浏览(49)
  • 【分页表格】Vue2 + Element UI实现自定义的分页表格组件(自定义Vue组件)

    这篇文章,主要介绍Vue2 + Element UI实现自定义的分页表格组件(自定义Vue组件)。 目录 一、分页表格 1.1、运行效果 1.2、运行环境 1.3、案例代码

    2024年02月11日
    浏览(59)
  • 【Django】列表数据Paginatior分页,动态返回页码,显示当前页、总页数、跳转页

    1、当返回数据较多,如设置每页展示10条,数据接近200条,返回页码范围1~20,前端每个页码都显示的话,就会出现页码超出当前页面,被遮挡的页码无法操作和显示不美观; 2、列表的所在页码,总分页数,跳转不在动态页面的页数 在使用paginator转化为Page对象后,获取到n

    2024年02月12日
    浏览(39)
  • 解决:element-ui分页器在将最后一页列表数据删完时,页面不刷新到最新数据

    一、问题: 在用element-ui分页器的时候,我将最后一页列表数据删完了,但是页面没刷新到最新数据。正常情况是,我删完最后一页数据后,分页器停留在上一页,并刷新列表数据,以下是删完后的页面展现 网络返回的数据说明 :(pageNo:当前页 pageSize:当前页展示的条数

    2024年02月20日
    浏览(41)
  • 前端Vue自定义加载中loading加载结束end组件 可用于分页展示 页面加载请求

    前端Vue自定义加载中loading加载结束end组件 可用于分页展示 页面加载请求, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13219 效果图如下: 实现代码如下: 使用方法 HTML代码实现部分 组件实现代码

    2024年02月11日
    浏览(57)
  • elementui el-table表格实现翻页和搜索均保持勾选状态(后端分页)

    需求: 不管是页面切换还是通过搜索获取数据,都要保持已选中的行保持勾选状态,同时将选中行的内容以标签的形式显示出来,当点击关闭标签时可以对应取消选中状态,点击行中的任意位置也可以切换选中状态,单独勾选复选框一样可以达到要求。 由于需求相对还是蛮

    2024年02月10日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包