Vue `vm. $ On ()` обратный вызов не работает в parent, когда событие отправляется из динамического компонента child - PullRequest
0 голосов
/ 29 декабря 2018

Возникла проблема, когда пользовательское событие (swap-components), генерируемое динамическим компонентом (A.vue или B.vue), неправильно прослушивается в родительском компоненте динамического компонента (HelloWorld.vue).

Вот источник на GitHub (созданный с помощью vue cli 3).

Вот демоверсия live, показывающая проблему .

В демонстрационной версии вы увидите, что нажатие кнопки в динамическом компоненте с цветом фона НЕ изменяет динамический компонент.Но при нажатии кнопки под цветом фона (который начинается с родительского элемента HelloWorld.vue), динамический компонент не изменяется.

Почему это происходит и как это исправить?


Ниже я скопирую содержимое 3 основных файлов, представляющих интерес, в этот пост:

  1. HelloWorld.vue (родитель)

  2. A.vue (подкомпонент, используемый в динамическом компоненте)

  3. B.vue (подкомпонент, используемый в динамическом компоненте)

HelloWorld.vue:

<template>
  <div>
    <h1>The dynamic components ⤵️</h1>
    <component
      :is="current"
      v-bind="dynamicProps"
    ></component>
    <button
      @click="click"
    >Click me to swap components from within the parent of the dynamic component</button>
  </div>
</template>

<script>
import A from "./A.vue";
import B from "./B.vue";

export default {
  data() {
    return {
      current: "A"
    };
  },
  computed: {
    dynamicProps() {
      return this.current === "A" ? { data: 11 } : { color: "black" };
    }
  },
  methods: {
    click() {
      this.$emit("swap-components");
    },
    swapComponents() {
      this.current = this.current === "A" ? "B" : "A";
    }
  },
  mounted() {
    this.$nextTick(() => {
      // Code that will run only after the
      // entire view has been rendered
      this.$on("swap-components", this.swapComponents);
    });
  },
  components: {
    A,
    B
  },
  props: {
    msg: String
  }
};
</script>

A.vue:

<template>
  <section id="A">
    <h1>Component A</h1>
    <p>Data prop sent from parent: "{{ data }}"</p>
    <button @click="click">Click me to swap components from within the dynamic component</button>
  </section>
</template>

<script>
export default {
  props: ["data"],
  methods: {
    click() {
      this.$emit("swap-components");
    }
  }
};
</script>

B.vue:

<template>
  <section id="B">
    <h1>Component B</h1>
    <p>Color prop sent from parent: "{{ color }}"</p>
    <button @click="click">Click me to swap components from within the dynamic component</button>
  </section>
</template>

<script>
export default {
  props: ["color"],
  methods: {
    click() {
      this.$emit("swap-components");
    }
  }
};
</script>

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Я предполагаю, что это потому, что прослушиватель событий прослушивает событие swap-components, испускаемое самим родительским компонентом.Возможно, вы можете исправить это, прослушивая событие swap-components от дочернего компонента, а затем отправляя событие родительскому компоненту.дочерний компонент ..

<template>
      <div>
        <h1>The dynamic components ⤵️</h1>
        <component
          :is="current"
          v-bind="dynamicProps"
          @swap-components="swapComponents"
        ></component>
        <button
          @click="click"
        >Click me to swap components from within the parent of the dynamic component</button>
      </div>
    </template>
0 голосов
/ 29 декабря 2018

this больше не привязан к контексту при использовании функции.Он ограничен только областью действия.Используйте функцию стрелки, чтобы разрешить this привязываться к родительскому контексту.

Изменить:

this.$nextTick(function() {

С:

this.$nextTick(() => {
...