私は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構文に従って、要素からイベントを発行することで、親からの子のイベントをリッスンできるはずですが、親はイベントをキャッチしていないようです。
どこがおかしいの?
$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>
このような単純な例では、(おそらく)何かを逃していない限り、コンポーネントのemit
tedイベントをリッスンするだけで済みます。たとえば、親要素には次のものがあります。
<HorizontalNavigation v-on:ChangeView={this.ChangeView} />
次に、子(HorizontalNavigation
)コンポーネントで、emit
'ChangeView'イベントを実行します。
this.$emit('ChangeView', e.target.dataset.section);
@craig_hの回答に対して行ったコメントに基づいて、私は自分で同様のコードでこれを試しましたが、それは私が必要としていたものでした。親にemit
する必要も、バスやvuexを使用する必要もありませんでした。
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>
動作するサンプルコードの実装を見つけることができますここ独自のコンテキスト。