Nuxt.js 必須スキル Vuex ストア を扱う


2018年10月15日

皆さんこんにちは。

先日久し振りに山に入って数km走ったら、
古傷の膝に水が貯まって翌日は立ち上がれず・・・
老化現象が急速に加速している20代の末ちゃんです。

アイキャッチはその山の中の景色です。

さて、今日はNuxt.jsを扱う上で必須の技術、
Vuex ストアについて簡単にご紹介します。

詳細については例によって公式サイトが詳しいので、
より詳しいことは公式サイトを確認してください。

Vuex ストアとは

Vuex ストアは、アプリケーションの状態を保持するコンテナです。
また、ストアはリアクティブに状態を変更することができ、
かつ、コンポーネント等から明示的にコミットしない限り状態が変更されないため、
意図せぬバグを発生させません。

どんなときに使う?

今回はNuxt.jsでウェブサイトを作成する際のパターンをご紹介しましょう。

Nuxt.jsでウェブサイトを作成するときに起こるよくある問題のひとつに、
ドロワーメニューなどを展開して遷移したあと、そのメニューが閉じない問題があります。

こんなときどうするかというと、Vuex ストアを使い、
グローバルにドロワーメニューの状態を管理します。

ドロワーメニューの状態をVuex ストアで管理する

早速実例でどのように実装するかご案内します。

テンプレート

例えば以下の様なコンポーネントがあったとします。
(HTML部分をpugで書いています)

<template lang="pug">
  .mobile-nav
    button.mobile-nav__trigger(
      @click='changeState',
    )
      my-menu(
        :isOpen='state',
      )

    nav.mobile-nav__body(
      :class='{ "is-open" : state }',
    )
      my-mobile-menu
</template>

my-menuはハンバーガーメニューの子コンポーネントです。
isOpenを渡して、開閉のコントールをしています。

.mobile-nav__bodyには直接css classをバインドして開閉のコントールをしています。

またstateにはBoolean型でデータが格納されています。
falseなら閉、trueなら開といった感じです。

Vuex ストア

ではstateの値をどこで管理しているかというと、
今回はstore/ToggleMenu.jsに格納しました。

/**
 * store/ToggleMenu.js
 *
 * モバイルのトグルメニューの状態管理
 */
export const state = () => ({
  menuOpen: false,
});

export const mutations = {
  toggle(state) {
    state.menuOpen = !state.menuOpen;
  },
  resetMenu(state) {
    state.menuOpen = false;
  },
};

これがToggleMenu.jsの全貌です。

まずstateに初期の状態を記述します。

次にmutationsに値を変更するためのメソッドを書き込みます。

toggle(state)

これはみての通り、state の値を反対に書き換えるメソッドです。
つまりメニューをクリックされたときの開閉のメソッドです。

resetMenu(state)

これは単純に state の値をfalseに変更します。
勘のいい人はお気づきでしょう。ページを読み込みの際にこのメソッドを実行します。

コンポーネントからVuex ストアを呼びだす

さて、コンポーネントから早速Vuex ストアを呼びだしてみましょう。

<script>
import MyMenu from '~/components/atoms/Header/Hamburger.vue';
import MyMobileMenu from '~/components/atoms/Header/MobileNav.vue';

const menuState = 'ToggleMenu';

export default {
  components: {
    MyMenu,
    MyMobileMenu,
  },
  computed: {
    state() {
      return this.$store.state[menuState].menuOpen;
    },
  },
  methods: {
    changeState() {
      const mutationName = 'toggle';
      this.$store.commit(`${menuState}/${mutationName}`);
    },
  },
};
</script>

まずVuex ストアのstateの値を、コンポーネント内の state に格納します。

computed: 部分がそうですね。

その次にストアの状態を切り替えるためのメソッドをmethods: に定義します。

あとはコンポーネントのボタン部分に@click='changeState'でメソッドを呼びだすだけです。

pages/**/*.vue で resetMenu を呼びだして状態をリセットする

<script>
const menuState = 'ToggleMenu';

export default {
  fetch({ store }) {
    const mutationName = 'resetMenu';
    store.commit(`${menuState}/${mutationName}`);
  },
};
</script>

fetch でレンダリング前にVuex ストアのデータを弄るのみですね!

まとめ

以上のコードはそのままコピーしてもお使いいただけるはずです。
なお Nuxt.js 2.1.0 で検証しています。

うーん、もっと簡単に実装できるようにならないかなぁと。
ドロワーなど頻繁に使うのだし、Web標準でこういうAPIがたくさんできるといいですね!

それではまたお会いしましょう。

Share Button