beta

Vue routerでルート変更の度に、inputで開いているメニューを閉じる方法

Vueアプリで、vue routerを使ってルート変更すると、inputパラメータで動的に開閉させる(トグルさせる)メニューボックスを閉じることができないので、閉じる(inputの値を変える)方法をまとめました。

公開日:2020年3月19日

課題

Vueでアプリを作る際には、CSSでメニューの開閉を制御することが多いと思います。

<input type="checkbox" id="ipt__site-main-menu" class="d-none" />
<div class="site-main-menu">
中身
</div>

こんな感じで、input:checkedのステータスで、メニューの場所を変えたりして開閉するメニューを作るケースですね。

通常のWebページの場合は、ページ遷移が伴う場合は自動的にcheckboxがfalseになってメニューが閉じるのですが、Vue + Vue Routerで構築したSPAアプリの場合、ルートが変更されてもページ遷移されないため、input:checkedの値がリセットされず、メニューが開いたままになってしまいます。

解決方法

router.beforeEachで処理する

Vue Routerにはルーティング前後に処理を入れる「router.beforeEach / router.afterEach」という関数が用意されているので、そちらを使います。

router.jsに下記のように書けばOKです。

router.beforeEach((to, from, next) => {
  const menuipt = document.getElementById('ipt__site-main-menu');
        menuipt.checked = false;
})

ルート変更を実行する前に、毎回input要素のcheckedをfalseにしています。

これなら毎回必ずメニューが閉じてくれます。

App.vueで処理する

routerレベルじゃなくて、Appレベルで制御したい場合は、App.vueに制御を書くのもOKです。

App.vueはルーティング時に必ず通りように作っていることが多いと思うので、watchに入れておけば、すべてのルーティングで処理を入れることができます。

watch: {
  $route(to) {
    const menuipt = document.getElementById('ipt__site-main-menu');
          menuipt.checked = false;

  }
}

処理している中身は、先ほどのrouter.beforeEachと同じです。


Vue routerでルート変更の度に、inputで開いているメニューを閉じる方法でした。

この他にも、

  • Vuexでinputのステートを保持して、全コンポーネントから処理する
  • router-linkを使わないで、ページ遷移専用メソッドを作って、そこでinputをfalseにする

など、いろいろやり方はありますが、単純なメニューだったら、こちらの方法が一番シンプルで使い勝手が良いかと思います。

: