NativeScript-Vueでサイドドロワーを出すビューを限定する

2 min read読了の目安(約1900字

動機・前提

nativescript-vue-multi-drawerで左端からスワイプで引き出せるサイドドロワーを作った(RadSideDrawerはバグが多く使いにくい)。サイドドロワーを出したくないページがある(記事の詳細ページ)。しかしデフォルトではどのビューでも左からスワイプすればでてきてしまう。issueなどを読むとmain.jsにおいて

main.js
Vue.use(MultiDrawer, {
  left: {
    canSwipeOpen: false,
  },
})

などとすればスワイプで開く動作をオフにできる。

問題

しかしこれは静的な値で、動的にVuex storeなどで変更することができない。たとえば次のようにすることが考えられる。まずサイドドロワーをオフにしたいビュー(ArticleDetails.vue)において、

ArticleDetails.vue
// ...
mounted() {
    store.commit('drawer/DISABLE_DRAWER')
  },
  destroyed() {
    store.commit('drawer/ENABLE_DRAWER')
  },
// ...

として、drawerモジュールのmutationsstate.drawer.canSwipeOpentrueにするENABLE_DRAWER()falseにするDISABLE_DRAWER()を用意する:

/store/drawer.js
const state = {
  canSwipeOpen: true,
}
const mutations = {
  ENABLE_DRAWER(state) {
    console.log('enabling drawer again...')
    state.canSwipeOpen = true
  },
  DISABLE_DRAWER(state) {
    console.log('disable drawer because user visited article details.')
    state.canSwipeOpen = false
  },
}

そしてこの値がリアクティブに変更されることを利用して、MultiDrawerを呼び出すときのオプションの値を変更する:

main.js
import store from '@/store'
Vue.use(MultiDrawer, {
  left: {
    canSwipeOpen: store.state.drawer.canSwipeOpen,
  },
})

しかしこうしても、drawerモジュール内のstatecanSwipeOpenの初期値をfalseに指定すると、この値をいかにmutateしようとも全てのページでオフになってしまう。

解決

NativeScript-VueのSlackチャンネルで質問したところ、NS-Vueの開発者rigor789が丁寧に教えてくれた。

App.vue
<template>
// ...
  <MultiDrawer :options="drawerOptions" />
// ...
</template>
<script>
// ...
  computed: {
    drawerOptions() {
      console.log('canSwipeOpen???', this.$store.state.drawer.canSwipeOpen)
      return {
        left: { canSwipeOpen: this.$store.state.drawer.canSwipeOpen },
      }
    },
  }
  // ...
}

とすればかんたんに動く。<MultiDrawer>:options=ができるなんて…聞いてない…そういうもんなの…?