Vue中v-model绑定了computed值,但setter不更新

代码大概是这个样子的:
<input type="checkbox" v-model="selectAllList[Index]" />

`

computed: {
    selectAllList: {
        get(){},
        set(){
            console.log('set');
        }
    }}

`

其中selectAllList的get其实就是依赖于一个数组,数组中的每一个值都是一个数组。当该数组的值全为true时,则selectAllList对应位置的值为true。也就是实现一个联动的效果。
`

{
    List : [ [ false , false ] , [ true , true , true ] , [ false , true ] ],
    selectAllList: [ false , true , false ]
}

`

相应的,我想要实现当改变selectAllList中的值的时候,也要改变对应数组List中的值,因此需要用set来改变。

但是现在不知道为什么改变v-model的值,setter不会触发。是因为我v-model绑定的是一个数组中的某一个值,引用对象值的改变不会触发到setter。那么应该如何绑定呢?

阅读 8k
4 个回答
  • 你想要的效果应该是这样:

image.png

  • 部分代码如下:
<el-checkbox v-model="selectAll" @change="select">全选</el-checkbox>
        <ul>
          <li v-for="(li,i) in list" :key="i">
            <el-checkbox
              v-model="selectChildrenAll[i].selected"
              @change="selectAllChild($event,i)"
            >全选</el-checkbox>
            <ul>
              <li v-for="(lii,ii) in li" :key="ii">
                <el-checkbox v-model="lii.selected">全选</el-checkbox>
              </li>
            </ul>
          </li>
        </ul>
        
         computed: {
    selectAll: {
      get() {
        return this.selectChildrenAll.every(item => item.selected);
      },
      set(val) {
        return val;
      }
    },
    selectChildrenAll() {
      let arr = [];
      this.list.forEach(item => {
        let res = item.every(e => e.selected);
        arr.push({ selected: res });
      });
      return arr;
    }
  },
  data() {
    return {
      list: [
        [{ selected: true }, { selected: false }],
        [{ selected: true }, { selected: true }, { selected: true }],
        [{ selected: false }, { selected: false }]
      ]
    };
  },
   methods: {
    // 某个子全选CheckBox
    selectAllChild(e, index) {
      this.list[index].forEach(item => {
        item.selected = e;
      });
    },
    // 顶层全选checkbox
    select(e) {
      this.list.forEach((item, i) => {
        this.selectAllChild(e, i);
      });
    }
  }   

造成这个的原因是:由于 JavaScript 的限制,Vue 不能检测数组的变动:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

你的需求应该是要做一个 全选/反选 的功能吧,总共有两层全选/反选checkbox



正确写法:this.$set(this.data,”key”,value')

mounted () {
  this.$set(this.student,"age", 24)
}

雷同问题

实际上我在vue的论坛上找到了类似的问题,但没有满意的答复。用其他的实现方式似乎都过于丑陋。

vuex解决思路

实际上vuex的官网上有过一个类似的解决方案。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题