我用Vue编写了一个简单的日历。通过使用v-来显示月份中的天,为此创建了$ refs数组。每个日期元素还具有唯一的ID。我想通过单击来突出显示一天,这有效。但是,每个月的同一天也会突出显示。例如,如果我单击5月25日,则即使我根据该元素的ID来切换类,也将突出显示每隔25日一次。
如何仅突出显示所选日期?
这是高亮方法的代码。
highlightDay(index) {
let selected = this.$refs.day[index].id;
if (!this.$refs.day[index].classList.contains("today")) {
this.$refs.day.forEach(el => {
if (el.classList.contains("selected-day")) {
el.classList.toggle("selected-day");
}
});
document
.getElementById(selected)
.classList.toggle("selected-day");
}
}
这里是项目的链接。 https://codepen.io/reticent67/pen/EzWomG
答案 0 :(得分:1)
您面临的问题来自通过$refs
使用DOM元素来存储您的
选定的日期。
我鼓励您将这种逻辑类型(我称之为jQuery逻辑,通常会导致复杂的DOM操作,即使在像您这样的简单情况下也是如此)转移到特定于SPA的逻辑中,在其中使用虚拟模型(通常称为vm
)作为真理的来源 1 。
回到您的组件,而不是将您选择的日期存储为当前呈现日期的id
,而是将其存储为一个包含3个元素的数组:[day, month, year]
2 。
要将其传递给渲染的层,应使用以下方法:
isSelected(index) {
return this.selectedDay === [index, this.month, this.year];
}
带有包含以下内容的日期标记:
<div
v-for="(date, date_index) in months[month].days"
:key="date_index"
:class="[{ 'selected-day': isSelected(date_index) }]">{{ date }}
</div>
我已经在您的示例here中实现了此功能。
注意,我还简化了highlightDay()
方法。我只是将selectedDay
设置为上述数组,或者如果它们相等则取消设置(以通过单击选定的数组来启用取消选择)。
[1]- 请注意,在更复杂的情况下,需要在应用程序组件之间共享真相来源,Vue提供了专门的模块用于管理数据的Vuex(但在此不使用)。
[2]- 为了清除观察者的数据(Vue用于监听突变),我将数组存储在selectedDay
中作为JSON字符串。