こんにちは、さるまりんです 🐒🔧
Vue.js や JavaScript で画面を作っていると、
いつの間にか使っているのが URLパラメータ。
?mode=edit&page=2
「とりあえず取れてるからOK」
「なんとなく動いてるからOK」
……そんな感じで、
僕も いい加減に扱ってしまっている ことがありました。
やっていて思うのは、
URLパラメータって あとから地味にハマりやすい んですよね。
ということで今回は、
- URLパラメータって何?
- JavaScriptでどう扱うのが安全?
- Vue.js で使うときの考え方
を、実際に試しながら整理してみます。
URLパラメータって、そもそも何?
URLパラメータは、URLの中の ? 以降の部分です。
https://example.com/list?mode=edit&page=2
この
?mode=edit&page=2
が クエリパラメータ。
よくある使い道は:
- 表示する内容(データ)の指定
- 表示モードの切り替え
- ページ番号
- フィルタ条件
- タブ状態の保持
つまり、
URLに画面の状態を保存している
というイメージになります。
シンプルな書き方(そして罠)
最初にやりがちなのが、これ。
const query = location.search;
console.log(query);
location.search で ? 以降がすべて取れます。
結果:
?mode=edit&page=2
ここから、
query.replace("?", "");
query.split("&");
……と、
自前でパースし始める パターン。
もちろんこれは動きますし、
仕組みを理解するには大事なことでもあります。
でも、やっているとこうなります。
- エンコードはどうする?
- 値が無い場合は?
- 同じキーが複数あったら?
「どうする?」がどんどん増えていきます。
みんな同じ問題にぶつかってきたんですよね。
だからこそ、ちゃんと用意されています。
URLSearchParams を使う
JavaScript には、最初から便利なAPIがあります。
const params = new URLSearchParams(location.search);
これで、クエリを安全に扱えるようになります。
取得
params.get("mode"); // "edit"
params.get("page"); // "2"
追加・更新
params.set("page", "3");
削除
params.delete("mode");
文字列操作を一切しなくてOK
というのが、かなり大きいです。
「setしたのにURLが変わらない?」問題
ここで、一度ハマりやすいポイントがあります。
params.set("page", "3");
これを実行しても、
ブラウザのURLは変わりません。
気持ちとしては、
?page=3 になってほしいですよね?
でも、なりません。
なぜかというと、
👉 URLSearchParams は
URLそのものを書き換えるものではない からです。
反映させるには、こうします。
const newUrl =
location.pathname + "?" + params.toString();
history.replaceState(null, "", newUrl);
これで、実際のURLが変わります。
ここで出てきた history、
履歴を操作しているんですね。
replaceState と pushState の違い
-
replaceState
→ 履歴を汚さない(今の状態を置き換える) pushState
→ 履歴を残したいとき(戻るボタン対応など)
この違い、意外と大事です。
hash (#…) を一緒に扱うときの注意
URLに hash がある場合:
/list?page=2#detail
そのまま location.pathname だけでURLを組み立てると、
hash が消えてしまう ことがあります。
安全に書くなら:
const newUrl =
location.pathname +
"?" + params.toString() +
location.hash;
URLは部品の組み合わせ
という意識で扱うと、
思わぬ事故を防げます。
Vue.js で使うときの考え方
Vue Router を使っていなくても、
- タブ切り替え
- フィルタ条件
- モーダル状態
を URL に残すだけで、
- リロードしても状態が戻る
- URLを共有できる
- デバッグが楽
というメリットがあります。
たとえば、こんな感じ。
mounted() {
const params = new URLSearchParams(location.search);
this.mode = params.get("mode") || "default";
}
初期値をURLから取る
これだけでも、かなり便利です。
URLは「画面状態の保存場所」
今回あらためて思ったのは、
URLはただの文字列じゃない
ということ。
ちゃんと考えて扱うと、
- 状態
- 意図
- 再現性
が全部、URLの中に残ります。
URLSearchParams を使うことで、
- 意図が伝わる
- コードが短くなる
- バグが減る
という恩恵もあります。
「なんとなく文字列操作」から
一歩進んで考えてみると、楽になります。
仕組みを用意してくれた人たちに感謝ですね。
次にやってみたいこと
- 実際の Vue コンポーネントでの応用
- 複数パラメータの扱い方
- フィルタUIとの組み合わせ
- hash と query の役割分担
このあたりは、
また別の記事でまとめたいと思います 🐒🔧
読んでくださってありがとうございました。
それではまた!