LoginSignup
5
3

More than 3 years have passed since last update.

【nuxt.js】layoutsからpagesのmethodsを叩き、戻り値をlayoutsで表示する

Last updated at Posted at 2020-05-17

かなり時間取られたので、記事のネタにして精神の安定を図ります。ちなみに私は「返り値」派ですが、「戻り値」の方が若干多数派っぽい?ですね。

やりたかった事

「layouts/header.vue」の?ボタンを押すと、「pages/hoge.vue」や「pages/poyo.vue」のmethods: generateHelp()を叩いて、その戻り値を「layouts/header.vue」に渡してダイアログに表示する、みたいなことをしたかった。methods: generateHelp()の無い「pages/huga.vue」については、何も起きないなりundefinedが返ってくるなり適当でいいやと。

図で表すと↓こんな感じ。
qiita.png

そもそもこの設計自体が間違ってる気がしないでもないです。何か良い案ございましたらご教示ください。

実現した方法

  1. ?ボタンを押すと'requireHelp'イベントを発火させる
  2. 「pages/hoge.vue」は'requireHelp'イベントを検知して、methods: generateHelp()を叩く
  3. methods: generateHelp()は処理の最後に、自身の戻り値を引数として'returnHelp'イベントを発火させる
  4. 「layouts/header.vue」は'returnHelp'イベントを検知して、引数をダイアログに表示させる
layouts/header.vue
<template>
  <h1>たいとる</h1>
  <button @click="clickHelpButton"></button>
  <nuxt />
</template>

<script>
export default {
  // 'returnHelp'イベントの検知(4の前半)
  created () {
    this.$nuxt.$on('returnHelp', (help) => {
      this.showDialog(help)
    })
  },

  // ページを離れる際に検知を終了
  // (書かないとどういった問題が起きるのか、誰か教えてください><)
  beforeDestroy () {
    this.$nuxt.$off('returnHelp')
  },

  methods: {
    // ボタンクリック時に各pagesへ向けて'requireHelp'イベント発火(1)
    clickHelpButton () {
      this.$nuxt.$emit('requireHelp')
    },
    // ダイアログを表示(4の後半)
    showDialog (help) {
      /* ダイアログを表示する処理 */
    }
  }
</script>
pages/hoge.vue
<script>
export default {
  // 'requireHelp'イベントの検知(2の前半)
  created () {
    this.$nuxt.$on('requireHelp', () => {
      this.generateHelp()
    })
  },

  // ページを離れる際に検知を終了
  beforeDestroy () {
    this.$nuxt.$off('requireHelp')
  },

  methods: {
    // ?ボタンが叩きたかったお目当ての関数(2の後半)
    generateHelp () {
      // なんかヘルプ内容を生成
      const help = 'ggrks'

      // layouts/header.vueに向けて'returnHelp'イベントを発火(3)
      this.$nuxt.$emit('returnHelp', help)
      return help
    }
  }
</script>

流れを図示すると↓こんな感じ。
2020-05-17_113259.png

うまくいかなかった方法

$refsを使う

「親コンポーネントから子コンポーネントのmethodsを触る方法」みたいな記事を参考にして、<nuxt ref="page" />としてthis.$refs.page.generateHelp()ってすれば直接叩けないかと思ったけど、駄目。this.$refs.pageが参照するのはnuxt自体(?)で、各pagesではない???(どう表現するのが正解なのか分かってない)

Vuex storeを経由する

ボタンを押したときにstoreを更新させようと思ったら、結局イベント発火が必要なのに気づいてやめた。layoutsからpages内の子コンポーネントのmethodsを……ってなったらstore経由した方が楽かもしれないが、そもそもその設計を見直した方が良さそう。

参考文献

[Nuxt.js] EventBusを使ってコンポーネント間で通信する
【Vue.js】親コンポーネントから子コンポーネントのメソッドを叩く

繰り返しになりますが、もっとこうしたらスマートだよ!って方法あれば教えてください。切に。

5
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3