vue分頁全選和單選操作

龍恩0707發表於2018-09-04
<!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>

 

相關文章