Реактивность: изменить свойство в массиве, примененное к событию окна - PullRequest
0 голосов
/ 26 апреля 2019

Простой вариант использования: определенные элементы должны получить активный класс, установив для свойства "active" значение true (v-bind: class).Свойство «active» устанавливается в цикле foreach, после проверки некоторых условий, в методе «handleScroll».

Это работает, если я вызываю «handleScroll» непосредственно в созданном жизненном цикле.

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

Если я вызываю «handleScroll» из события окна, реактивность теряется.

Изменение

public created() {
  ...
  this.handleScroll();
}

на

public created() {
  ...
  window.addEventListener("scroll", this.handleScroll);
}

не работает,Метод выполняется, но реактивность в шаблоне теряется.

Вопрос : Как установить эти свойства в событии глобального окна и назначить их обратно для просмотра?

Ответы [ 4 ]

1 голос
/ 26 апреля 2019

Попробуйте установить значение с помощью Vue.set, как описано в разделе caveats , например:

Vue.set(sidebarItems[index], 'active', true)

или

Vue.set(sidebarItems, index, { ...sidebarItems[index], { active: true})
1 голос
/ 26 апреля 2019

Это может быть проблема реактивности Vue.

Попробуйте изменить ссылку на объект, создав глубокую копию, используя 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))
}
0 голосов
/ 26 апреля 2019

Вам придется использовать либо вычисляемое свойство, либо функцию, которая напрямую вызывается из vue для отражения изменений. Ниже код должен работать -

<template>
  <div class="c-sidebar">
    <p
      v-for="(sidebarItem, index) in sidebarItems"
      :key="index"
      :class="getActiveClass(index)"
    >
      {{ 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
      }
    ];
}

  public getActiveClass(index: number) {
    return index === 1 ? 'active': '';
  }
}
</script>
0 голосов
/ 26 апреля 2019

Нет очевидных причин, по которым это не сработало бы, основываясь исключительно на коде, показанном здесь. Предупреждение реактивности Vue касается добавления / удаления элементов массива, а не изменения атрибутов.

Я бы сделал тройную уверенность в том, что метод на самом деле запущен, с некоторым console.log:

this.sidebarItems.forEach((sidebarItem: SidebarItem, index) => {
  if (index == 1) {
    sidebarItem.active = true;
    console.log('on: ' + sidebarItem)
  } else {
    sidebarItem.active = false;
    console.log('off: ' + sidebarItem)
  }
});

Если это не дает вашего ответа, было бы лучше воссоздать вашу проблему в jsfiddle. Это, вероятно, покажет вам, что вам нужно. Если этого не произойдет, вы можете опубликовать скрипку здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...