select/deselect v-for 中的单个元素
select/deselect single element in v-for
我正在尝试使用 v-for
创建一个选项列表,您一次只能在其中选择一个选项。效果很好,但我无法取消选择该选项。
<div id="main">
<ul>
<li
v-for="l in list"
id="l.key"
@click="selectone(l.key, l.isSelected)"
v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
> {{ l.tec }} </li>
<ul>
</div>
JS
new Vue({
el:"#main",
data: {
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
},
methods: {
selectone: function(k, o) {
for( i = 0; i < this.list.length; i ++ ) {
if(this.list[i].isSelected == true ) {
this.list[i].isSelected = false
}
}
this.list[k].isSelected = !this.list[k].isSelected;
}
}
})
CSS
.selected {
background:lightpink;
}
.notselected {
background:lightblue;
}
我的循环不应该在每次单击元素时停用所有选项吗?
在 selectone()
中,您为 所有 列表项设置 isSelected=false
,然后 尝试 切换所选列表项的 isSelected
,它之前刚刚设置为 false
(即,"toggle" 将始终为所选项目设置 isSelected=true
)。
循环应该排除所选项目的键:
selectone(key) {
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].key !== key) {
this.list[i].isSelected = false
}
}
// this.toggleSelection(key)
}
但是切换代码本身需要 bug-fix 才能正确查找列表项。 selectone()
的第一个参数是列表项的 key
属性。为了从 list
数组中按键获取项目,您必须搜索 list
,例如,使用 Array.prototype.find()
:
toggleSelection(key) {
const listItem = this.list.find(item => item.key === key)
if (listItem) {
listItem.isSelected = !listItem.isSelected
}
}
new Vue({
el: '#app',
data: {
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
},
methods: {
selectone(key) {
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].key !== key) {
this.list[i].isSelected = false
}
}
this.toggleSelection(key)
},
toggleSelection(key) {
const listItem = this.list.find(item => item.key === key)
if (listItem) {
listItem.isSelected = !listItem.isSelected
}
}
}
})
.selected {
background:lightpink;
}
.notselected {
background:lightblue;
}
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<ul>
<li
v-for="l in list"
id="l.key"
@click="selectone(l.key, l.isSelected)"
v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
> {{ l.tec }} </li>
<ul>
</div>
或者,您可以跟踪所选索引,将其设置在项目的 click
-处理程序中,并根据与所选索引匹配的项目索引设置 class
绑定:
// template
<li
v-for="(l, index) in list"
id="l.key"
@click="selectedIndex = index"
v-bind:class="{ selected: index === selectedIndex, notselected: index !== selectedIndex }"
> {{ l.tec }} </li>
// script
export default {
data() {
return {
selectedIndex: -1,
...
}
}
}
new Vue({
el: '#app',
data: {
selectedIndex: -1,
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
}
})
.selected {
background:lightpink;
}
.notselected {
background:lightblue;
}
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<ul>
<li
v-for="(l, index) in list"
id="l.key"
@click="selectedIndex = index"
v-bind:class="{ selected : index === selectedIndex, notselected : index !== selectedIndex }"
> {{ l.tec }} </li>
<ul>
</div>
你的关闭。试试这个:(未经测试)
<div id="main">
<ul>
<li
v-for="(l,index) in list"
id="l.key"
@click="selectone(l, index)"
v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
> {{ l.tec }} </li>
<ul>
</div>
JS
new Vue({
el:"#main",
data: {
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
},
methods: {
selectone:function(l, index){
for( i = 0; i < this.list.length; i ++ ) {
this.list[i].isSelected = false
}
l.isSelected = true;
}
}
}
})
解释一下你在函数中没有使用变量 k。那应该是整个对象而不是索引
我正在尝试使用 v-for
创建一个选项列表,您一次只能在其中选择一个选项。效果很好,但我无法取消选择该选项。
<div id="main">
<ul>
<li
v-for="l in list"
id="l.key"
@click="selectone(l.key, l.isSelected)"
v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
> {{ l.tec }} </li>
<ul>
</div>
JS
new Vue({
el:"#main",
data: {
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
},
methods: {
selectone: function(k, o) {
for( i = 0; i < this.list.length; i ++ ) {
if(this.list[i].isSelected == true ) {
this.list[i].isSelected = false
}
}
this.list[k].isSelected = !this.list[k].isSelected;
}
}
})
CSS
.selected {
background:lightpink;
}
.notselected {
background:lightblue;
}
我的循环不应该在每次单击元素时停用所有选项吗?
在 selectone()
中,您为 所有 列表项设置 isSelected=false
,然后 尝试 切换所选列表项的 isSelected
,它之前刚刚设置为 false
(即,"toggle" 将始终为所选项目设置 isSelected=true
)。
循环应该排除所选项目的键:
selectone(key) {
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].key !== key) {
this.list[i].isSelected = false
}
}
// this.toggleSelection(key)
}
但是切换代码本身需要 bug-fix 才能正确查找列表项。 selectone()
的第一个参数是列表项的 key
属性。为了从 list
数组中按键获取项目,您必须搜索 list
,例如,使用 Array.prototype.find()
:
toggleSelection(key) {
const listItem = this.list.find(item => item.key === key)
if (listItem) {
listItem.isSelected = !listItem.isSelected
}
}
new Vue({
el: '#app',
data: {
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
},
methods: {
selectone(key) {
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].key !== key) {
this.list[i].isSelected = false
}
}
this.toggleSelection(key)
},
toggleSelection(key) {
const listItem = this.list.find(item => item.key === key)
if (listItem) {
listItem.isSelected = !listItem.isSelected
}
}
}
})
.selected {
background:lightpink;
}
.notselected {
background:lightblue;
}
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<ul>
<li
v-for="l in list"
id="l.key"
@click="selectone(l.key, l.isSelected)"
v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
> {{ l.tec }} </li>
<ul>
</div>
或者,您可以跟踪所选索引,将其设置在项目的 click
-处理程序中,并根据与所选索引匹配的项目索引设置 class
绑定:
// template
<li
v-for="(l, index) in list"
id="l.key"
@click="selectedIndex = index"
v-bind:class="{ selected: index === selectedIndex, notselected: index !== selectedIndex }"
> {{ l.tec }} </li>
// script
export default {
data() {
return {
selectedIndex: -1,
...
}
}
}
new Vue({
el: '#app',
data: {
selectedIndex: -1,
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
}
})
.selected {
background:lightpink;
}
.notselected {
background:lightblue;
}
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<ul>
<li
v-for="(l, index) in list"
id="l.key"
@click="selectedIndex = index"
v-bind:class="{ selected : index === selectedIndex, notselected : index !== selectedIndex }"
> {{ l.tec }} </li>
<ul>
</div>
你的关闭。试试这个:(未经测试)
<div id="main">
<ul>
<li
v-for="(l,index) in list"
id="l.key"
@click="selectone(l, index)"
v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
> {{ l.tec }} </li>
<ul>
</div>
JS
new Vue({
el:"#main",
data: {
list: [
{key:"0", tec:"html", isSelected:false},
{key:"1", tec:"css", isSelected:false},
{key:"2", tec:"JS", isSelected:false},
{key:"3", tec:"Git", isSelected:false},
{key:"4", tec:"NodeJS", isSelected:false},
{key:"5", tec:"Postgres", isSelected:false}
]
},
methods: {
selectone:function(l, index){
for( i = 0; i < this.list.length; i ++ ) {
this.list[i].isSelected = false
}
l.isSelected = true;
}
}
}
})
解释一下你在函数中没有使用变量 k。那应该是整个对象而不是索引