忘れないように記録しとこ

カバの樹

Vue Routerを使っていてURLのqueryを変更しても反映されない時の対応

2021年1月19日

はじめに

Vue Routerを使う場面が増えてきた今日この頃です。

URLのqueryを変更した時に、Viewが反映されない現象が発生しました。

実はそこまで気にする必要は無いのでは?と見てみぬふりをして開発をしていたのですが、クライアントから指摘が入り(気づくな!)対応することにしました。

 

Vue Routerは問題無い

URLからqueryを取得してくるはずのVue Routerが反映されないのはおかしくないか?
というわけで、公式のドキュメントに記載されている、下記のwatchを使用して中身が変更されているか確認します。

watch: {
  $route (to, from) {
    console.log(to, from);
  }
}

 

結果

上記の画像から$routeが更新されているのが分かるので、Vue Router側は問題無いはずです。

 

問題はVueのdataが更新されないから

Vue Routermodehashモードを使ってると、URLにが付くためアンカーアクセスとしてブラウザに認識されます
そのためURLのqueryを変更しても、ブラウザがリロードされず、Vueが再構成されることもないので、dataが反映されないのだと思われます。

 

watchの反応でdataへ反映させる

めちゃくちゃ力技なのですが、watchが$routeの変更に反応した時にdataの中身を更新する手法を取ります。

 

動作イメージ

 

ソースコード

data: function(){
  return {
    search: this.$route.query.search ? decodeURI(this.$route.query.search) : '',
    selectCategory: this.$route.query.selectCategory ? decodeURI(this.$route.query.selectCategory) : '',
    selectDate: this.$route.query.selectDate ? decodeURI(this.$route.query.selectDate) : null
  }
},
watch: {
  $route (to, from) {
    const watch = [
      {queryKey: 'search', dataKey:'search', defaultValue:''},
      {queryKey: 'selectCategory', dataKey:'selectCategory', defaultValue:''},
      {queryKey: 'selectDate', dataKey:'selectDate', defaultValue: null},
   ];
   for (let i=0; i<watch.length; ++i) {
     let key = watch[i].queryKey;
     let defaultValue = watch[i].defaultValue;
     let dataKey = watch[i].dataKey;
     if(this.$route.query[key] || (from.query[key] && !this.$route.query[key]))
       this[dataKey] = this.$route.query[key] ? decodeURI(this.$route.query[key]) : defaultValue;
     }
   }
}

$route内のwatch定数にqueryを配列で設定します。
watchforで回して、更新が合った場合はdataを更新します。
queryが削除されていた場合は、defaultValueでデフォルト値を設定します。

 

動作確認をされたい方は、以下のURLをどぞー

https://kabanoki.github.io/VueJsLibrary/curstom-vue-table/filter/index2-4.html

 

  • B!