vue中的checkbox全选和反选

前几天有个博客园的朋友问小颖,小颖之前写的vue2.0在table中实现全选和反选  、Vue.js实现checkbox的全选和反选,为什么他将里面的js复制下来,但是实现不了全选和反选。小颖当时看他给的截图,也没太明白,后来手动巧了一下,发现一个疑问,虽然问题是解决了,但是至于为什么小颖还是不太明白,希望有哪位vue大神看到了能帮忙解答一下,嘻嘻,小颖先在这里提前说声:谢谢啦,嘻嘻。

      我们先来看看第一种实现全选和反选的方法:直接使用   script   标签调用vue。

复制代码
    <div id="app">
        <input type="checkbox" v-model='checked' v-on:click='checkedAll'> 全选{{checked}}
        <template v-for="(list,index) in checkboxList">
            <input type="checkbox" v-model='checkList' :value="list.id"> {{list.product_inf}}
        </template>
        {{checkList}}
    </div>
复制代码
复制代码
    <script>
    var vm = new Vue({
        el: '#app',
        data: {
            checkboxList: [{
                'id': '1',
                'product_inf': '女士银手链'
            }, {
                'id': '2',
                'product_inf': '女士银手镯'
            }, {
                'id': '3',
                'product_inf': '女士银耳环'
            }],
            checked: false, //全选框
            checkList: []
        },
        methods: {
            checkedAll: function() {
                var _this = this;
                console.log(_this.checkList);
                console.log(_this.checked);
                if (!_this.checked) { //实现反选
                    _this.checkList = [];
                } else { //实现全选
                    _this.checkList = [];
                    this.checkboxList.forEach(function(item, index) {
                        _this.checkList.push(item.id);
                    });
                }
            }
        },
        watch: {
            'checkList': {
                handler: function(val, oldVal) {
                    if (val.length === this.checkboxList.length) {
                        this.checked = true;
                    } else {
                        this.checked = false;
                    }
                },
                deep: true
            }
        },
    })
    </script>
复制代码

打印结果:

 

 

 

第二种实现方式:在vue脚手架环境中:

复制代码
  <div class="container">
    <input type="checkbox" v-model='checked' v-on:click='checkedAll'> 全选{{checked}}
    <template v-for="(list,index) in checkboxList">
      <input type="checkbox" v-model='checkList' :value="list.id">{{list.product_inf}}
    </template>
    {{checkList}}
    <button @click="ceshi">ceshi</button>
  </div>
复制代码
复制代码
<script>
export default {
  data() {
    return {
      checkboxList: [{
        'id': '1',
        'product_inf': '女士银手链'
      }, {
        'id': '2',
        'product_inf': '女士银手镯'
      }, {
        'id': '3',
        'product_inf': '女士银耳环'
      }],
      checked: false, //全选框
      checkList: []
    }
  },
  methods: {
    ceshi: function() {
      console.log(this.checked)
    },
    checkedAll: function() {
      var _this = this;
      console.log(_this.checkList);
      console.log(_this.checked);
      this.$nextTick(function() {
        // DOM 现在更新了
        console.log(_this.checked);
      });
      if (_this.checked) { //实现反选
        _this.checkList = [];
      } else { //实现全选
        _this.checkList = [];
        _this.checkboxList.forEach(function(item, index) {
          _this.checkList.push(item.id);
        });
      }
    }
  },
  watch: { //深度 watcher
    'checkList': {
      handler: function(val, oldVal) {
        if (val.length === this.checkboxList.length) {
          this.checked = true;
        } else {
          this.checked = false;
        }
      },
      deep: true
    }
  }
}

</script>
复制代码

 打印结果:

大家看完上面的四张图有没有发现一个问题:

同样是在 click 事件 checkedAll 中执行:   console.log(_this.checked);  但是结果却不一样,第一种环境中,在修改数据之后checkedAll事件中的_this.checked立马就变了,但是在第二种环境中,在修改数据之后checkedAll事件中的_this.checked不会立马变,而是等到下一次调用时,才发生变化,但是在 click 事件 checkedAll   的this.$nextTick事件中,能将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。

    所以在两种环境中,判断全选和反选的条件也不一样:

第一种

复制代码
                if (!_this.checked) { //实现反选
                    _this.checkList = [];
                } else { //实现全选
                    _this.checkList = [];
                    this.checkboxList.forEach(function(item, index) {
                        _this.checkList.push(item.id);
                    });
                }
复制代码

第二种:

复制代码
      if (_this.checked) { //实现反选
        _this.checkList = [];
      } else { //实现全选
        _this.checkList = [];
        _this.checkboxList.forEach(function(item, index) {
          _this.checkList.push(item.id);
        });
      }
复制代码

当然也可以将第二种修改为:

复制代码
    checkedAll: function() {
      var _this = this;
      console.log(_this.checkList);
      this.$nextTick(function() {
        console.log(_this.checked);
        // DOM 现在更新了
        if (!_this.checked) { //实现反选
          _this.checkList = [];
        } else { //实现全选
          _this.checkList = [];
          _this.checkboxList.forEach(function(item, index) {
            _this.checkList.push(item.id);
          });
        }
      });
    }
复制代码

好啦今天的分享就到这里啦,希望大神们能帮小颖解答这个疑惑呦。。。。嘻嘻。

疑问解决啦,哈哈,原来是版本问题,之前博友给的低版本的,用了最新的版本后发现也要用Vue.nextTick方法

用新版本后,点击事件:

复制代码
            checkedAll: function() {
                var _this = this;
                console.log(_this.checkList);
                Vue.nextTick(function() {
                    // DOM 更新了
                    console.log(_this.checked);
                    if (!_this.checked) { //实现反选
                        _this.checkList = [];
                    } else { //实现全选
                        _this.checkList = [];
                        _this.checkboxList.forEach(function(item, index) {
                            _this.checkList.push(item.id);
                        });
                    }
                })
            }
复制代码

 

本博客文章大多为原创,转载请请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2018-01-18 17:14  挨踢人啊  阅读(22633)  评论(1编辑  收藏  举报