代码改变世界

vue分页全选和单选操作

2018-09-04 19:32  龙恩0707  阅读(3329)  评论(3编辑  收藏  举报
<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      ul,li {list-style: none;}
      .tb-table-list {
          width: 100%
      }
      .tb-table-list.title h3 {
        float: left;
        font-size: 16px;
        margin: 0;
        margin-top: 6px;
        font-weight: 400
      }
      .tb-table-list.title.operation {
        float: right;
        font-size: 16px
      }
      .tb-table-list .tb-table2 {
        width: 100%;
        float: left;
        border: 1px solid #dfe6ec;
        border-right: none;
        margin-top: 10px;
        margin-bottom: 30px;
        border-bottom: none
      }
      .tb-table-list .tb-table2 th {
        background-color: #f2f2f2;
        height: 40px
      }
      .tb-table-list .tb-table2 tr {
        height: 40px
      }
      .tb-table-list .tb-table2 td, 
      .tb-table-list .tb-table2 th {
        position: relative;
        border-bottom: 1px solid #dfe6ec;
        text-overflow: ellipsis;
        vertical-align: middle;
        padding: 5px;
        text-align: center;
        border-right: 1px solid #dfe6ec
      }
      .tb-table-list .tb-table2 td.cell, .tb-table-list .tb-table2 th.cell {
        text-align: center;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
        text-overflow: ellipsis;
        white-space: normal;
        word-break: break -all;
        padding-right: 2px;
        padding-left: 2px;
        overflow: hidden
      }
      .tb-table-list .tb-table2 td.noDatas, 
      .tb-table-list .tb-table2 th.noDatas {
        text-align: left
      }
      .tb-table-list .tb-table2.tb-arrow-up {
        position: absolute;
        bottom: -1px;
        color: #d6e4f0;
        font-size: 22px;
        height: 13px;
        background: #fff;
        left: 45%;
        z-index: 100
      }
      .tb-table-list .tb-table2.cursor-item {
        cursor: pointer
      }
      .tb-table-style .tb-table2 td {
        text-align: center
      }
      .tb-table-style td.thead {
        background: #ebf0f4;
        color: #000
      }
      .tb-table-style .tb-table2 .current {
        background-color: #f44336;
        color: #fff
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class='tb-table-list'>
        <table class="tb-table2" cellspacing="0" cellpadding="0">
          <thead>
            <tr>
              <th width="60" v-if="datas.length > 0">
                <div class="cell">
                  <input @change="checkedAll" v-model='checkAllBox' type='checkbox' />
                </div>
              </th>
              <th width="200"><div class="cell">姓名</div></th>
              <th width="200"><div class="cell">年龄</div></th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="datas.length > 0" v-for="(item, index) in datas">
              <td>
                <div class="cell">
                  <input @change="singleSelect(item, index)" v-model="item.isCheck" type='checkbox' />
                </div>
              </td>
              <td><div class="cell">{{item.name}}</div></td>
              <td><div class="cell">{{item.age}}</div></td>
            </tr>
            <tr v-if="datas.length === 0">
              <td colspan="3"><div class="cell noDatas">暂无数据</div></td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </body>
  <script src="https://tugenhua0707.github.io/vue/vue-watch/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        // 保存选中的项
        saveSelectItems: [],
        checkAllBox: false,
        datas: [
          { 'name': '姓名', 'age': '22', 'isCheck': false },
          { 'name': '姓名', 'age': '22', 'isCheck': false },
          { 'name': '姓名', 'age': '22', 'isCheck': false },
          { 'name': '姓名', 'age': '22', 'isCheck': false },
          { 'name': '姓名', 'age': '22', 'isCheck': false }
        ]
      },
      methods: {
        // 全选
        checkedAll() {
          if (this.datas.length > 0) {
            for (let i = 0; i < this.datas.length; i++) {
              if (this.checkAllBox) {
                this.$set(this.datas[i], 'isCheck', true);
                // 全选操作
                this.checkAllIsChecked(this.datas[i], true);
              } else {
                this.$set(this.datas[i], 'isCheck', false);
                this.checkAllIsChecked(this.datas[i], false);
              }
            }
          }
        },
        checkAllIsChecked(item, isflag) {
          let count = 0;
          if (isflag) {
            if (this.saveSelectItems.length > 0) {
              for (let i = 0; i < this.saveSelectItems.length; i++) {
                if (this.saveSelectItems[i].id === item.id) {
                  this.saveSelectItems[i].isCheck = isflag;
                  count++;
                }
              }
              if (count < 1) {
                item.isCheck = isflag;
                this.saveSelectItems.push(item);
              }
            } else {
              item.isCheck = isflag;
              this.saveSelectItems.push(item);
            }
          } else {
            if (this.saveSelectItems.length > 0) {
              for (let j = 0; j < this.saveSelectItems.length; j++) {
                if (this.saveSelectItems[j].id === item.id) {
                  this.saveSelectItems.splice(j, 1);
                }
              }
            }
          }
        },
        /*
         单选
         @param item 当前选中的项
         @param index 当前的索引
        */
        singleSelect(item, index) {
          this.$set(this.datas[index], 'isCheck', item.isCheck);
          if (item.isCheck) {
            this.saveSelectItems.push(item);
          } else {
            this.delItem(item);
          }
          const checkCount = this.isCheckAllFunc();
          if (checkCount === this.datas.length) {
            this.checkAllBox = true;
          } else {
            this.checkAllBox = false;
          }
        },
        isCheckAllFunc() {
          let count = 0;
          if (this.datas.length > 0) {
            for (let i = 0; i < this.datas.length; i++) {
              if (this.datas[i].isCheck) {
                count++;
              }
            }
          }
          return count;
        },
        delItem(item) {
          if (this.saveSelectItems.length > 0) {
            for (let i = 0; i < this.saveSelectItems.length; i++) {
              if (this.saveSelectItems[i].id === item.id) {
                this.saveSelectItems.splice(i, 1);
              }
            }
          }
        },
        /*
          分页请求后返回新数据的时候,该每一项设置属性 isCheck 为 false,但是当数组内部有保存的数据时,
          且该保存的数据id和请求返回回来的id相同的话,就把该项选中,比如我勾选了第一页中的某一项,会把
          该项的id保存到数组内部去,当切换到第二页的时候,那么再返回到第一页的时候,会获取该id是否与数组的
          id是否相同,如果相同的话,就把该项数据选中
        */
        addIsChecked(datas) {
          let count = 0;
          if (datas.length > 0) {
            for (let i = 0; i < datas.length; i++) {
              datas[i].isCheck = false;
              if (this.saveSelectItems.length > 0) {
                for (let j = 0; j < this.saveSelectItems.length; j++) {
                  if (datas[i].id === this.saveSelectItems[j].id) {
                    datas[i].isCheck = true;
                    count++;
                  }
                }
              }
            }
          }
          if (this.datas.length !== 0 && (count === this.pageSize)) {
            this.checkAllBox = true;
          }
          return datas;
        },
        query() {
          /* 
           ajax请求 
           Promise.all([this.$store.dispatch('commonActionGet', ['cashRemitSuspend', obj])]).then((res) => {
              if (请求成功的话) {
                // 这句话的含义是 分页请求数据 第一页全选了,切换到第二页的时候,全选按钮不勾选
                this.checkAllBox = false; 

                // 返回数据,如果有数据的话,给每一项设置属性 isCheck = false
                // 如果当前保存的数据id和分页中的数据id相同的话,就默认勾选该项。这就是当第一页勾选了,点击第二页的时候,
                // 我会把当前的勾选的id保存到数组里面去,为了再返回到第一页的时候,默认选中该项
                
                this.datas = res[0].data ? this.addIsChecked(res[0].data) : [];
              }
           })
          */
        }
      }
    })
  </script>
</html>