Simple use case: Specific elements should get an active class by setting property "active" to true (v-bind:class). The property "active" is set within a foreach loop, after checking some conditions, within method "handleScroll".
This works, if I call "handleScroll" directly in created lifecycle.
<template>
<div class="c-sidebar">
<p
v-for="(sidebarItem, index) in sidebarItems"
v-bind:key="index"
v-bind:class="{ 'active': sidebarItem.active }"
>
{{ sidebarItem.label }}
</p>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from "vue-property-decorator";
import {SidebarItem, SidebarNavItem} from "../../Interfaces";
@Component
export default class Sidebar extends Vue {
sidebarItems: SidebarItem[];
public created() {
this.sidebarItems = [
{
label: "First item",
active: true
},
{
label: "Second item",
active: false
}
];
this.handleScroll();
}
public handleScroll() {
this.sidebarItems.forEach((sidebarItem: SidebarItem, index) => {
if (index == 1) {
sidebarItem.active = true;
} else {
sidebarItem.active = false;
}
});
}
}
</script>
If I call "handleScroll" from within a window event, reactivity gets lost.
Change
public created() {
...
this.handleScroll();
}
to
public created() {
...
window.addEventListener("scroll", this.handleScroll);
}
does not work. The method is executed, but reactivity in template gets lost.
Question: How to I set these properties in a global window event and assign them back to view?
It might be Vue reactivity problem.
Please try changing object reference by creating a deep copy using JSON.parse(JSON.stringify())
public handleScroll() {
this.sidebarItems.forEach((sidebarItem: SidebarItem, index) => {
if (index == 1) {
sidebarItem.active = true;
} else {
sidebarItem.active = false;
}
});
this.sidebarItems = JSON.parse(JSON.stringify(this.sidebarItems))
}