VueJS 主复选框切换数组值
Posted
技术标签:
【中文标题】VueJS 主复选框切换数组值【英文标题】:VueJS Master Checkbox Toggle with array values 【发布时间】:2018-08-06 11:47:54 【问题描述】:我正在使用 VueJS,但在一系列复选框上实现两个功能时遇到问题。
首先,我的复选框是动态构建的。 我需要实现一个主“切换”复选框,单击该复选框时会选中或取消选中所有其他复选框。 我需要在模型中保留一组选中项。此脚本为我提供了切换复选框,但不填充“checkedNames”数组。我尝试在名称复选框中添加一个 v-model,但它只是检查了所有内容,但仍然没有填充数组。
new Vue(
el: '#boxes',
data:
checked: null,
checkedNames: [],
teams: [
name: 'team a',
id: 'team-a',
checked: null,
members: [
'id': 1,
'name': 'Dave'
,
'id': 2,
'name': 'Dee'
,
'id': 3,
'name': 'Dozy'
,
'id': 4,
'name': 'Beaky'
,
'id': 5,
'name': 'Mick'
,
'id': 6,
'name': 'Tich'
]
,
name: 'team b',
id: 'team-b',
checked: null,
members: [
'id': 7,
'name': 'John'
,
'id': 8,
'name': 'Paul'
,
'id': 9,
'name': 'George'
,
'id': 10,
'name': 'Ringo'
]
]
);
<div id='boxes'>
<ul>
<li v-for="team in teams" style="width: 100px; float:left">
<div>
<input type="checkbox" class="form-check form-check-inline" v-bind:id="team.id" v-model="team.checked">
<label v-bind:for="team.id"><strong> team.name </strong></label>
</div>
<ul class="countries_list">
<li v-for="member in team.members">
<input type="checkbox" class="form-check form-check-inline" v-bind:id="member.id" v-bind.checked="checked : team.checked">
<label v-bind:for="member.id"> member.name </label>
</li>
</ul>
</li>
</ul>
<br>
<span>Checked names: checkedNames </span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
https://jsfiddle.net/50wL7mdz/133578/
有人能指出我正确的方向吗?
【问题讨论】:
如果两个团队中都有Ringo
怎么办?
这是可能的,但它会是一个不同的 Ringo。即,它将有一个唯一的 id。成员将始终只属于一个团队
【参考方案1】:
我的看法:
1.为每个成员添加了'checked'属性。
2.将每个成员的复选框与每个成员的v-model="member.checked"
绑定
3.为团队复选框绑定“更改”事件,如果单击,则为每个成员设置member.checked=team.checked
4. 将checkedNamed 转换为计算属性,使用for-loop 或reduce 打印出所有成员都已检查。
new Vue(
el: '#boxes',
computed:
computed_checkedNames: function()
let temp = '';
for(teamIndex in this.teams)
temp += '[team=' + this.teams[teamIndex].name + ']'
for(memberIndex in this.teams[teamIndex].members)
temp += this.teams[teamIndex].members[memberIndex].checked ? this.teams[teamIndex].members[memberIndex].name + ',' : ''
temp += ','
return temp
,
data:
checked: null,
//checkedNames: [],
teams: [
name: 'team a',
id: 'team-a',
checked: false,
members: [
'id': 1,
'name': 'Dave',
checked: false
,
'id': 2,
'name': 'Dee',
checked: false
,
'id': 3,
'name': 'Dozy',
checked: false
,
'id': 4,
'name': 'Beaky',
checked: false
,
'id': 5,
'name': 'Mick',
checked: false
,
'id': 6,
'name': 'Tich',
checked: false
]
,
name: 'team b',
id: 'team-b',
checked: null,
members: [
'id': 1,
'name': 'John',
checked: false
,
'id': 2,
'name': 'Paul',
checked: false
,
'id': 3,
'name': 'George',
checked: false
,
'id': 4,
'name': 'Ringo',
checked: false
,
'id': 6,
'name': 'Tich',
checked: false
]
]
);
<div id='boxes'>
<ul>
<li v-for="team in teams" style="width: 100px; float:left">
<div>
<input type="checkbox" class="form-check form-check-inline" v-bind:id="team.id" v-model="team.checked" v-on:change="team.members.forEach(function(value, key)value.checked=team.checked);">
<label v-bind:for="team.id"><strong> team.name </strong></label>
</div>
<ul class="countries_list">
<li v-for="member in team.members">
<input type="checkbox" class="form-check form-check-inline" v-bind:id="member.id" v-model="member.checked">
<label v-bind:for="member.id"> member.name </label>
</li>
</ul>
</li>
</ul>
<br>
<span style="background-color:#8d9bb2">Checked names: computed_checkedNames </span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
【讨论】:
你如何处理价值观相同的团队? @OnahOnallySunday 我更新了在team a
和team b
中添加了一个元素=id: 6, name: 'Tich'
的答案,看起来工作正常。【参考方案2】:
这有点棘手。我认为您需要使用 @change
来控制所有内容,因为您有 checkAll 复选框功能。
在我这边,我不需要那些父 checked
属性,我只需要子选中属性来区分选中/未选中。基本上这是一个后备,因为您必须添加额外的属性checked
。
检查并尝试运行下面的sn-p。
new Vue(
el : '#boxes',
data :
teams: [
name: 'team a',
id: 'team-a',
members: [
'id': 1, 'name' : 'Dave', 'checked': false,
'id': 2, 'name' : 'Dee', 'checked': false,
'id': 3, 'name' : 'Dozy', 'checked': false,
'id': 4, 'name' : 'Beaky', 'checked': true,
'id': 5, 'name' : 'Mick', 'checked': false,
'id': 6, 'name' : 'Tich', 'checked': false
]
,
name: 'team b',
id: 'team-b',
members: [
'id': 7, 'name' : 'John', 'checked': false,
'id': 8, 'name' : 'Paul', 'checked': false,
'id': 9, 'name' : 'George', 'checked': false,
'id': 10, 'name' : 'Ringo', 'checked': false,
'id': 11, 'name' : 'Mick', 'checked': false
]
]
,
computed:
getSelectedMembers: function()
var selectedMem = [];
for(var teamIdx in this.teams)
var members = this.teams[teamIdx].members;
for(var memberIdx in members)
if (members[memberIdx].checked)
selectedMem.push(members[memberIdx].id);
return selectedMem;
,
methods:
checkAll: function(idx, $event)
var member = this.teams[idx].members;
for(var memberIdx in member)
member[memberIdx].checked = $event.target.checked;
);
.disp
display: inline-block;
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>
<script src="https://unpkg.com/vue"></script>
<div id='boxes'>
<ul>
<li v-for="(team, index) in teams" style="width: 200px; float:left">
<div>
<input type="checkbox" class="form-check form-check-inline" v-bind:id="team.id" @change="checkAll(index, $event)" >
<label v-bind:for="team.id"><strong> team.name </strong></label>
</div>
<ul class="countries_list">
<li v-for="member in team.members">
<input type="checkbox" class="form-check form-check-inline" v-bind:id="member.id" v-bind.checked="checked : member.checked" :value="member.name" @change="member.checked = !member.checked">
<label v-bind:for="member.id"> member.name </label>
</li>
</ul>
</li>
</ul>
<div>getSelectedMembers: getSelectedMembers </div>
<br><br><br><br><br><br><br><br><br>
<div class="disp" v-for="team in teams">
<ul><strong> team.id </strong>
<li v-for="member in team.members" v-if="member.checked">member.name</li>
</ul>
</div>
</div>
【讨论】:
谢谢@Dencio。首先,道歉。由于在我应该在床上的深夜问这个问题,我在我的脚本中打错了字。 id 值实际上应该是唯一的。我已经修改了我的问题。也就是说,您的解决方案非常接近。唯一的事情是我需要一个结果数组。这会为每个团队生成一个数组。这可以实现吗? @Typhoon101 sup,你的意思是单个数组只用于names
?它的id
怎么样?所以我可以尝试重现它。
因为我只需要一个数组,是的,我想一组 id 将是唯一的方法。没事儿。谢谢
@Typhoon101 伙计,你介意这种阵列吗? selectedIds: [teamId2: [memId1, memId2, memId3],teamId2: [memId1, memId2, memId3]]
最终,我需要一个仅包含选定项目的数组,例如:selectedId: [1,6,8,10,3]。但是数组是通过 Ajax 传递给一个 php 脚本的,所以如果需要的话,可能会有一些清理服务器端。【参考方案3】:
首先,每个复选框都缺少value
。添加它并将v-model
值分配给checkedNames
可以直接使用,但它当然不会全选。我在@change
上添加了一个新方法来解决这个问题,请参阅下面的小提琴:
https://jsfiddle.net/50wL7mdz/133688/
正如其他人指出的那样,这里的问题是您的 checkedNames
变量中没有唯一用户。将 user.name
更改为 user.id
不会解决此问题,因为您的 ID 只是索引(您有 1、2、3 等的重复项)。
【讨论】:
以上是关于VueJS 主复选框切换数组值的主要内容,如果未能解决你的问题,请参考以下文章