数组中对象的属性在所有元素都更改时是反应性的,但如果只有一些元素更改则不是
Posted
技术标签:
【中文标题】数组中对象的属性在所有元素都更改时是反应性的,但如果只有一些元素更改则不是【英文标题】: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 添加为一个,我已准备好接受答案。
【参考方案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>
【讨论】:
以上是关于数组中对象的属性在所有元素都更改时是反应性的,但如果只有一些元素更改则不是的主要内容,如果未能解决你的问题,请参考以下文章