【问题标题】:Property of object in array is reactive when all elements are changed, but not if only some are changed数组中对象的属性在所有元素都更改时是反应性的,但如果只有一些元素更改则不是
【发布时间】:2021-02-06 02:50:50
【问题描述】:

我有这个 selectAllToggle 函数,它反应性地选择或取消选择数组中的所有元素。响应式,当使用 selectButton 时,浏览器中的所有复选框都显示为选中或取消选中。

当手动选择一个或多个(但不是全部)复选框时会出现问题。如果选中任何复选框,则 selectButtonName 更改为“取消全选”,按下时,我希望它取消全选。 我正确更新了数组的代码,因为它将数组中的每个学生的“selected”属性设置为 false,但它的反应性不起作用 - 手动选择的学生的复选框保持勾选状态在浏览器中。

selectAllToggle: function(key, row, $event) {
    var setTo = false;
    var newname = "Select All";
    if (this.selectButtonName === "Select All") {
        setTo = true;
        newname = "Deselect All";
    }
    if (this.selectButtonName === "Deselect All") {
        setTo = false;
        newname = "Select All";
    }

    if (this.students.length > 0) {
        for (var i = 0; i < this.students.length; i++) {
            this.students[i]['selected'] = setTo;
        }
    }
    this.selectButtonName = newname;
    
    console.log(this.students);    //shows the correct 'selected' state for all
},

视图看起来像这样(使用 vue-tables-2)

<v-client-table 
   v-if="gridReady" 
   v-model.sync="students" 
   :columns="gridcolumns" 
   :options="gridoptions"
   ref="grid">

<input type="checkbox" 
    slot="selected" 
    slot-scope="{row, update}" 
    v-model="row.selected"
    @change="selectStudent('select', row, $event)">

</v-client-table>

我可以做些什么来使这个函数反应?

【问题讨论】:

  • 也许 Vue 没有观察到学生对象。您如何加载学生数据?它是否在 data 属性中预先声明?每个学生对象是否有一个selected 属性您将其分配给数据(好)还是您稍后添加这些属性(坏)?
  • 学生数据在 data 属性中预先声明,但从后端加载时没有 selected 属性 - 它是在 vue js 中添加的。我可以在后端添加这个属性 - 似乎是一个很好的建议,所以会在这里评论它是否有效
  • @DecadeMoon 我现在为从后端加载的每个学生选择了 = false,但仍然存在同样的问题。但这不是你建议的我想的那样。因为事情的顺序(据我所知)是:数据属性>挂载> refreshGrid(从后端加载学生数据)。我能想到的从一开始就将它放在 data 属性中的唯一方法是,如果学生作为道具进来,然后在数据中我有 localStudents: this.students。
  • 后端不应该使用selected 属性污染学生对象,这是一个仅限前端的属性。您只需按顺序执行 (1) 获取学生数据,(2) 遍历每个学生并添加 selected 属性,(3) 将学生数组分配给 this。否则你需要使用Vue.set
  • @DecadeMoon 我之前试过 Vue.set,可能用错了。现在我让它工作了,但是解决它的方法是在 selectStudent 函数中也使用 Vue.set,这是一次选择一个学生时使用的。谢谢 - 你的知识真的帮助了我。如果您将您的 cmets 添加为一个,我已准备好接受答案。

标签: vue.js vuejs2 vue-tables-2


【解决方案1】:

对于在一个或多个元素选择后取消选择,您可以使用computed property 作为下面的 sn-p 进行反应性执行。

new Vue({
  el: '#app',

  data: {
    selected: [],
    clientList: [1, 2, 3, 4, 5]

  },
  computed: {
    selectAll: {
      get: function() {
        return this.selected.length > 0 &&
          this.selected.length <= this.clientList.length
      },
      set: function(value) {
        let list = [];
        if (value) {
          this.selected = this.clientList
        } else {
          this.selected = []
        }

      }
    }
  },
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <title>Document</title>
</head>

<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.7/vue.js"></script>

  <div id='app'>
    <table id="example1" class="table table-bordered table-striped">
      <thead>
        <tr>
          <th>Client Name</th>
          <th style="width: 10%"><input type="checkbox" v-model="selectAll" /></th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item,index) in clientList">
          <td style="font-weight: bold;width: 75%">{{item}}
          </td>
          <td style="width: 25%">
            <input type="checkbox" :value="item" v-model="selected" />
          </td>
        </tr>
      </tbody>
    </table>
  </div>


</body>

</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-06
    相关资源
    最近更新 更多