我有一周的天数,就像下面的可切换按钮一样:
单击该按钮将在ON
和OFF
之间切换(复选框为checked
)
注意:下面的代码不起作用,单击按钮时会显示undefined
<template>
<label
v-for="(day, index) in days"
:key="index"
class="flex items-center justify-center border border-gray-500 rounded cursor-pointer py-2"
:class="day.state ? 'text-white bg-gray-500' : 'text-gray-500 bg-white'"
:for="`checked-${day.index}`"
>
<input
:id="`checked-${ day.index }`"
type="checkbox"
class="absolute opacity-0 w-0 h-0"
@click="check"
v-model="selectedDays"
:value="index"
/>
{{ day.label }}
</label>
</template>
<script>
export default {
inheritAttrs: false,
data() {
return {
days: {
Sunday: {
label: 'Sun',
state: true
},
Monday: {
label: 'Mon',
state: false
},
Tuesday: {
label: 'Tue',
state: false
},
Wednesday: {
label: 'Wed',
state: false
},
Thursday: {
label: 'Thu',
state: false
},
Friday: {
label: 'Fri',
state: false
},
Saturday: {
label: 'Sat',
state: false
}
},
selectedDays: []
}
},
methods: {
clickToggle() {
this.toggle(!this.state)
},
toggle(state) {
this.state = state
},
check() {
console.log(this.selectedDays);
}
}
}
</script>
我的问题:
selectedDays
方法还是days
可以自行处理?没有任何必要。参见我的示例,我仅工作于v-model指令。
对于selectedDays
,更好的方法是计算属性。这是最佳做法,更容易。
<template>
<div>
<label
v-for="(day, index) in days"
:key="index"
class="flex items-center justify-center border border-gray-500 rounded cursor-pointer py-2"
:class="day.state ? 'text-white bg-gray-500' : 'text-gray-500 bg-white'"
>
<input type="checkbox" v-model="day.state" />
{{ day.label }}
</label>
<div>{{ selectedDays }}</div>
</div>
</template>
<script>
export default {
inheritAttrs: false,
data() {
return {
days: {
Sunday: { label: 'Sun', state: true },
Monday: { label: 'Mon', state: false },
Tuesday: { label: 'Tue', state: false },
Wednesday: { label: 'Wed', state: false },
Thursday: { label: 'Thu', state: false },
Friday: { label: 'Fri', state: false },
Saturday: { label: 'Sat', state: false },
},
};
},
computed: {
selectedDays() {
let result = [];
for (let key in this.days) {
if (this.days[key].state) {
result.push(this.days[key]);
}
}
return result;
},
},
};
</script>
您应该使用@nput
事件而不是@click
,在事件处理程序中传递索引并按days
的方式更改this.days[index].state=!this.days[index].state;
this.$set(this.days,index,this.days[index])
数组,并将复选框绑定到days[index].state
:
new Vue({
el: '#app',
data() {
return {
days: {
Sunday: {
label: 'Sun',
state: true
},
Monday: {
label: 'Mon',
state: false
},
Tuesday: {
label: 'Tue',
state: false
},
Wednesday: {
label: 'Wed',
state: false
},
Thursday: {
label: 'Thu',
state: false
},
Friday: {
label: 'Fri',
state: false
},
Saturday: {
label: 'Sat',
state: false
}
},
selectedDays: []
}
},
methods: {
clickToggle() {
this.toggle(!this.state)
},
toggle(state) {
this.state = state
},
check(index) {
this.days[index].state=!this.days[index].state;
this.$set(this.days,index,this.days[index])
console.log(this.selectedDays);
}
}
})
<body>
<div id="app">
<label v-for="(day, index) in days" :key="index" class="flex items-center justify-center border border-gray-500 rounded cursor-pointer py-2" :class="day.state ? 'text-white bg-gray-500' : 'text-gray-500 bg-white'" :for="`checked-${day.index}`">
<input
:id="`checked-${ day.index }`"
type="checkbox"
class="absolute opacity-0 w-0 h-0"
@input="check(index)"
v-model="days[index].state"
:value="day"
/>
{{ day.label }}
</label>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
我建议另一种方法(我删除了不必要的逻辑/样式):
<template>
<div v-for="(day, index) in days"
key="index">
<label>
{{days[index].label}}
</label>
<input
type="checkbox"
v-model="days[index].state"
/>
{{ day.label }}
</div>
</template>
<script>
export default {
data() {
return {
days: [
Sunday: {
label: 'Sun',
state: true
},
Monday: {
label: 'Mon',
state: false
},
Tuesday: {
label: 'Tue',
state: false
},
Wednesday: {
label: 'Wed',
state: false
},
Thursday: {
label: 'Thu',
state: false
},
Friday: {
label: 'Fri',
state: false
},
Saturday: {
label: 'Sat',
state: false
}
}
}
}
}
</script>