ユーザビリティ!ページ移動してもVueの状態を保持する方法

こんにちは!フリーランス・エンジニアの 九保すこひ です。

さてさて、前回は【Vue】wordpressのRest APIからデータを取得して一覧表示するという記事をお届けしました。

まだご覧になっていない方のために簡単に説明すると、この記事は「wordpressから取得した記事データを使って、Vueで表示する」といった内容になっています。そして、その表示内容は「選択されたカテゴリによって表示が変わる」ようになっていました。

実はメインの目的がwordpressからのデータ取得だったので省略したのですが、実際のサイトでこのまま実装すると、ひとつユーザビリティとしては足りない部分があったりします。

それは・・・

もしページ移動して、ブラウザの戻るボタンをクリックされてしまうとVueの内容は初期化されてしまう

というものです。

これは例えば、ある特定のキーワードで検索して、そこからページ移動をしたとすると、その後「戻る」ボタンを使って戻ってこられても検索結果が初期化されてしまい、「えーっ、また検索しなきゃいけないのかよ・・・😫」となってしまうという意味になります。

そこで!

今回は、ページ移動した後でもVueの変数の内容を保持するテクニックをご紹介したいと思います。

ぜひ皆さんのお役に立てると嬉しいです😊✨

開発環境: Vue 2.6

どうやって変数の内容を保持するのか?

まず、変数の中身をブラウザで保持するにはいくつか方法があって、例えば、

  • Cookie
  • Local storage

などにその内容を保存しておいて後で取り出すという方法があるのですが、今回はもっとシンプルに実装する方法を使います。

そして、それはどんな方法かというと「URLのハッシュ値#を使った」方法です。ハッシュ値とは、例えばこんなサンプルになります。

https://example.com#test

ハッシュ値は、ページ内の特定の位置に自動的に移動させるためによく使われるのですが、今回はこのハッシュ値にVueの変数を含ませて実装していきます。

実装する内容

ハッシュ値を使ったサンプルのために、今回は以下のような機能をもったページを作っていきます。

  • 5色(赤、青、黄色、白、黒)を一覧表示する
  • 色のうちの1つがクリックされたら「選択された色」として表示
  • そして、選択された色はページでリロードしようと、戻るボタンで戻ってこられても保持できるようにする

では、実際のコードをみていきましょう!

実際のコード

それほどコードは長くないので完成版のソースコードをご覧ください。

<html>
<head>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="p-4 bg-secondary">
<div id="app" class="container">
    <h1 class="mb-4">ブラウザの戻るボタンを押されてもパラメータを保持するサンプル</h1>
    <div class="row">
        <div class="col-2" v-for="color in colors">
            <div class="m-3 text-center" :style="{background:color.code}">
                <a :href="'#id='+ color.id" :style="{color:color.textColor}" v-text="color.name"></a>
            </div>
        </div>
    </div>
    <div class="row" v-if="selectedColor">
        <div class="col-3">
            <div class="m-3 text-center" :style="{background:selectedColor.code, color:selectedColor.textColor}">
                選択された色:<span v-text="selectedColor.name"></span>
            </div>
        </div>
    </div>
    <hr>
    <div class="row">
        <div class="col-12 m-3">
            <div class="bg-light p-3">
                <a href="https://google.com">外部サイト(Google)へ移動</a>
            </div>
        </div>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script>

    new Vue({
        el: '#app',
        data: {
            colors: [
                { id: 1, name: '赤', code: '#ff0000', textColor: '#ffffff'},
                { id: 2, name: '青', code: '#0000ff', textColor: '#ffffff'},
                { id: 3, name: '黄色', code: '#ffff00', textColor: '#000000'},
                { id: 4, name: '白', code: '#ffffff', textColor: '#000000'},
                { id: 5, name: '黒', code: '#000000', textColor: '#ffffff'},
            ],
            selectedColorId: ''
        },
        methods: {
            parseHash: function() { // ハッシュからパラメータを取り出す

                const hash = location.hash.substr(1);
                const hashes = hash.split(',');

                for(let i = 0 ; i < hashes.length ; i++) {

                    let hashKeyValue = hashes[i].split('=');
                    let key = hashKeyValue[0];
                    let value = hashKeyValue[1];

                    if(value) {

                        if(key === 'id') {

                            this.selectedColorId = parseInt(value);

                        }

                    }

                }

            }
        },
        computed: {
            selectedColor() {

                // 選択された色のデータを取得する
                return this.colors.find(color => color.id === this.selectedColorId);

            }
        },
        mounted() {

            window.addEventListener('hashchange', this.parseHash);
            this.parseHash();

        }
    });

</script>
</body>
</html>

まず、この中で一番重要なのは、parseHash()です。

今回のコードは以下のようなハッシュ値でVueの値を保持することを想定しているのですが、parseHash()はこの内容を分解して値を復活させるメソッドになっています。

https://example.com#key1=value1,key2=value2

ただし、今回選択された色のキーはidを使いますので、実際には以下の部分でハッシュ値から値を復活させることになります。

if(key === 'id') {

    this.selectedColorId = parseInt(value);

}

そして、次に重要な部分はmounted()です。

mounted() {

    window.addEventListener('hashchange', this.parseHash);
    this.parseHash();

}

ここでは、まずhashchangeというあまり耳慣れないJavaScriptイベントを設定していますが、これは「ハッシュ値が変更になったときに起動するイベント」になります。(もちろん実行するのは先ほどのparseHash()です)

また、戻るボタンで戻ってきた場合やページがリロードされたときのことも想定して直接parseHash()を実行していることにも注目してください。

そして最後は、以下の色リンクの部分です。

<a :href="'#id='+ color.id" :style="{color:color.textColor}" v-text="color.name"></a>

少し分かりにくいかもしれませんので、Vueでレンダリングしたサンプルをご覧ください。

<a href="#id=1" style="color: rgb(255, 255, 255);">赤</a>

つまり、リンク自体にはクリックイベントは全く存在せず、href=""でハッシュ値を変更することで、先ほど説明したhashchangeイベントが起動するようになっているという仕組みです。

あとは、これまでのVueの記事を参考にしていただけると問題なく理解できるかと思います。

テストしてみる

では実際にテストをしてみましょう!

まずはページを表示したところです。

では、黄色をクリックしてみましょう。

※ この時点でハッシュはhttps://*****/vue_keep_params#id=3になっています。

では、この状態で一回ページ下に用意した外部サイト(Google)に移動してみます。

もちろん、Googleのトップページが表示されます。

では、ここから戻るボタンをクリックして先ほどのページに戻ってみましょう。

はい!

画像のように選択された黄色のデータは保持されたままです。
これは#id=3からデータを復活させたからですね。

お疲れ様でした😊✨

ダウンロードする

今回実際に開発したソースコードを以下からダウンロードすることができます。

CDNを使っているので、展開したらすぐ試せますよ✨

ページ移動してもVueの状態を保持する方法

おわりに

ということで、今回はVueのデータをページ移動やリロードがあっても保持するテクニックをご紹介しました。

このテクニックを使えば、検索や絞り込みなどにも幅広く使えると思うのでぜひ活用してみてくださいね。

ではでは〜!

この記事が役立ちましたらシェアお願いします😊✨ by 九保すこひ
また、わかりにくい部分がありましたらお問い合わせからお気軽にご連絡ください。
このエントリーをはてなブックマークに追加       follow us in feedly