web-dev-qa-db-ja.com

vue.js、es6構文で子から親へのイベントを$ emit

私はVue.jsにかなり慣れていないので、ES6構文とvue-class-component。子から親にイベントを発行しようとしているときに問題が発生しています。

デフォルトのVue.js構文のロジックに従いましたが、親が子によって発行されたイベントをキャッチできないようです。コード:

子コンポーネント

クリックイベントリスナーをすべての<li>。イベントを発行する関数を呼び出します。イベントリスナーは親で定義されます。

 export default class HorizontalNavigation {

  handleClick (e) {
    e.preventDefault();
    // console.log(e.target.dataset.section);
    this.$emit('ChangeView', e.target.dataset.section);
  }

  render (h) {
    return (
      <div class={ style.horizontalNavigation } >
        <div class='sections-wrapper'>
          <div class={ style.sections }>
            <ol>
              <li><a on-click={ this.handleClick } href='#1' data-section='1' class='selected'>We are</a></li>
              <li><a on-click={ this.handleClick } href='#2' data-section='2'>Services</a></li>
              <li><a on-click={ this.handleClick } href='#3' data-section='3'>Cases</a></li>
              <li><a on-click={ this.handleClick } href='#4' data-section='4'>Studio</a></li>
              <li><a on-click={ this.handleClick } href='#5' data-section='5'>Career</a></li>
              <li><a on-click={ this.handleClick } href='#6' data-section='6'>Contact</a></li>
            </ol>

            <span class='filling-line' aria-hidden='true'></span>
          </div>
        </div>
      </div>
    );
  }
}

親コンポーネント

export default class ViewsContainer {

  ChangeView (data) {
    console.log(data);
  }

  render (h) {
      return (
        <div class={ style.restrictOverflow } >
          <HorizontalNavigation />
          <main class={ style.viewsContainer } on-ChangeView={ this.ChangeView     } >
            <SingleView dataSection='weare' id='1' class='selected' />
            <SingleView dataSection='services' id='2' />
            <SingleView dataSection='cases' id='3' />
            <SingleView dataSection='studio' id='4' />
            <SingleView dataSection='career' id='5' />
            <SingleView dataSection='contact' id='6' />
          </main>
        </div>
      );
    }
}

Vue.js構文に従って、要素からイベントを発行することで、親からの子のイベントをリッスンできるはずですが、親はイベントをキャッチしていないようです。

どこがおかしいの?

7
Lou

$emitを受け取るビューモデルで$emitを使用するか、busを使用するか、または https://vuex.vuejs.org/en/introを使用する必要があります。 .html

親に直接送信する

最も簡単な方法は、子から親コンポーネントに直接$emitするだけです:

this.$parent.$emit('ChangeView', e.target.dataset.section);

これは[〜#〜] ok [〜#〜]ですが、コンポーネントの長いチェーンがある場合は$emitする必要がありますチェーン内の各$parent

イベントバスを介した放出

Vue=を使用すると、非常に簡単にグローバルイベントバスを作成できます。メインコンポーネントでVueのインスタンスを作成すると、アプリケーションの他のすべてのコンポーネントがemitイベントに対応し、onを使用してそれらのイベントに対応します。

var bus = new Vue({});
var vm = new Vue({
  methods: {
    changeView() {
      bus.$emit('ChangeView', e.target.dataset.section);
    }
  });

$rootに送信することもできますが、これは推奨されません。ただし、appが非常に複雑になる場合は、代わりにVues独自の状態管理システム vuex を使用することを検討してください。

イベントを聞く

$emitを使用して特定のイベントをリッスンして、ビューモデルで$onをリッスンできます。

    var vm = new Vue({
      created() {
         this.$on('ChangeView', section => {
            console.log(section);
          });
      }
    );

これはバスを使用している場合も同様ですが、代わりにバスを参照するだけです。

bus.$on('ChangeView, ...);

また、v-onを使用してHTMLで直接使用することもできます。

<div v-on:ChangeView="doSomething"></div>
36
craig_h

このような単純な例では、(おそらく)何かを逃していない限り、コンポーネントのemittedイベントをリッスンするだけで済みます。たとえば、親要素には次のものがあります。

<HorizontalNavigation v-on:ChangeView={this.ChangeView} />

次に、子(HorizontalNavigation)コンポーネントで、emit 'ChangeView'イベントを実行します。

this.$emit('ChangeView', e.target.dataset.section);

@craig_hの回答に対して行ったコメントに基づいて、私は自分で同様のコードでこれを試しましたが、それは私が必要としていたものでした。親にemitする必要も、バスやvuexを使用する必要もありませんでした。

3
cam8001

Vueでは、イベントを発行することで、子から親コンポーネントまで通信できます子コンポーネントは、$emit親コンポーネントは次のようにリッスンします:

子コンポーネント:

<template>
  <div>
    <button @click="this.handleClick">Click me!</button>
  </div>
</template>

<script>
export default {
  name: "BaseButton",
  methods: {
    handleClick: function() {
      this.$emit("clickFromChildComponent");
    }
  }
};
</script>

<style scoped>

</style>

親コンポーネント:

<template>
  <div class="home">
    <h1>Passing a event from child up to parent!</h1>
    <BaseButton @clickFromChildComponent="handleClickInParent"/>
  </div>
</template>

<script>
import BaseButton from "./BaseButton";

export default {
  components: {
    BaseButton
  },
  name: "Home",
  methods: {
    handleClickInParent: function() {
      alert('Event accessed from parent!');
    }
  }
};
</script>

<style scoped>

</style>

動作するサンプルコードの実装を見つけることができますここ独自のコンテキスト。

1
Manuel Abascal