在日历组件中按元素ID切换类突出显示每个月的同一日期

时间:2019-05-24 19:22:32

标签: javascript vue.js vuejs2

我用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

1 个答案:

答案 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字符串。