Vue.jsとonsenuiを使ってスライダーメニューを作って見よう


はじめまして、PMをやっているtatsukenと申します。はじめまして
研修の一環でvue.js、expressを書くことがあったので、そのことを中心にまとめていきたいと思います。

はじめに

今回はonsenuiというネイティブライクなUIを作る事のできるCSSフレームワークを使ってスライダーメニューを作って行きたいと思います。
onsenuiはVue.jsにも対応しています。Vue.jsの他にはjQuery、AngularJS 1.x、AngularJS 2+、Reactなどにも対応しています。

出来上がりはこんな感じ

必要な環境

  • Vue.js
  • Vuex

実装

インストール

  • onsenuiのインストール(今回はVue.js対応のmoduleをインストールします)
    • npm install vue-onsenui -s
    • npm install onsenui -s
  • Vuexのインストール
    • npm install vuex -s

画面の作成

App.vueに以下を追加してください

App.vue
<template>
  <v-ons-page id="app">
    <v-ons-splitter>
      <v-ons-splitter-side
        swipeable
        collapse
        width="250px"
        :animation="$ons.platform.isAndroid() ? 'overlay' : 'reveal'"
        :open.sync="menuIsOpen"
      >
        <menu-page></menu-page>
      </v-ons-splitter-side>
      <v-ons-splitter-content>
        <router-view></router-view>
      </v-ons-splitter-content>
    </v-ons-splitter>
  </v-ons-page>
</template>

ここでスライドメニューの制御を行って行きます。スライドメニューのおおもとになる部分だと思ってください。
次にサイドメニューのcomponentを作っていきます。components/以下に任意のコンポーネントを作ってください。今回は components/Sidemenu.vueという感じで作成しました。

Sidemenu.vue
<template>
  <v-ons-page>
    <v-ons-toolbar modifier="transparent"></v-ons-toolbar>
    <div class="header"></div>
    <v-ons-list-title>Sample</v-ons-list-title>
    <v-ons-list>
      <v-ons-list>
        <v-ons-list-item modifier="chevron">
          <div class="left">
            <v-ons-icon icon="md-home"></v-ons-icon>
          </div>
          <div class="center">hoge1</div>
        </v-ons-list-item>
        <v-ons-list-item modifier="chevron">
          <div class="left">
            <v-ons-icon icon="md-home"></v-ons-icon>
          </div>
          <div class="center">hoge2</div>
        </v-ons-list-item>
        <v-ons-list-item modifier="chevron">
          <div class="left">
            <v-ons-icon icon="md-home"></v-ons-icon>
          </div>
          <div class="center">hoge3</div>
        </v-ons-list-item>
      </v-ons-list>
    </v-ons-list>
  </v-ons-page>

次は実際にメニューバーを描画するconponentを作っていきます。今回はvue-cliなどで作成されるcomponents/HelloWorld.vueに以下を記述していきます。

HelloWorld.vue
<template>
  <v-ons-page>
    <v-ons-toolbar class="home-toolbar">
      <div class="left">
        <v-ons-toolbar-button @click="$store.commit('splitter/toggle')">
          <v-ons-icon icon="ion-navicon, material:md-menu"></v-ons-icon>
        </v-ons-toolbar-button>
      </div>
      <div class="center">{{ msg }}</div>
    </v-ons-toolbar>
  </v-ons-page>
</template>

ここで<v-ons-icon icon="ion-navicon, material:md-menu"></v-ons-icon>でメニューバーを描画しています。
main.jsに以下を追記してください

main.js
import Vue from 'vue'
import App from './App'
import VueOnsen from 'vue-onsenui';
import 'onsenui/css/onsenui.css'
import 'onsenui/css/onsen-css-components.css'
import store from './store'
Vue.use(VueOnsen);
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
 store,
  components: {
    App,
  },
  template: '<App/>'
})

そしてsrc/store.jsというファイルを作成してください。基本的にどこに作成しても構いませんがmain.jsでstore.jsを読み込むディレクトリが変わってきますのでそこだけ注意してください。
store.jsに以下を追記してください。

store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    splitter: {
      namespaced: true,
      state: {
        open: false
      },
      mutations: {
        toggle(state, shouldOpen) {
          if (typeof shouldOpen === 'boolean') {
            state.open = shouldOpen
          } else {
            state.open = !state.open
          }
        }
      }
    }
  }
})

確認してみる

ここで以下のようにメニューバーが描画されていれば成功です。

動きを付けていく

この状態ではハンバーガーメニューを押しても何も反応しません。
ここからは動きを付けていきたいと思います。App.vueに以下を追記してください。

App.vue
<script>
import MenuPage from "./components/Sidemenu";
export default {
  name: "App",
  components: {
    MenuPage
  },
  computed: {
    menuIsOpen: {
      get() {
        return this.$store.state.splitter.open;
      },
      set(newValue) {
        this.$store.commit("splitter/toggle", newValue);
      }
    }
  }
};
</script>

最後に

これで無事サンプルのような動きが実現できたと思います。
今回はvuexを使っているので少し難しく見えるかもしれませんがぜひチャレンジしてみてください。
間違いなどあれば指摘していただけると幸いです。