【Vue + vue-cli】vue-routerでパラメーターを設定、取得
目次
今回はvue-routerにて、パラメータの設定と取得の方法についてまとめたいと思います。
なお、今回使用するデータもいつも通り下記記事と同様のものを使用します。
https://www.dailyupblog.com/web_development/742/
※vue-cliを使用しています。
それでは行きましょう。
パラメーターとは?
そもそもパラメーターとは何なのか?
簡単にまとめようと思います。
パラメーターとは、URLの末尾に付け加える変数のことです。
この変数にデータを格納することでサーバーにデータを送ったりすることが可能になります。
例えば、投稿型のサイトを作ったとして、投稿詳細ページを表示する際に、URLのパラメータによってデータベースから取得する記事データを判別し、内容を表示します。
https://www.〇〇.com?変数=値
上記のように、URLの末尾に「?」をつけてその後ろに「変数名=値」の形式でつけます。
投稿型サイトの投稿詳細ページをページIDのパラメーターをつけて表示する内容を出しわけるとします。
その場合は以下のようになります。
https://www.〇〇.com?id=1
Vueでパラメーターを設定する
Vueにてパラメーターを設定する方法です。
Vue-routerでページ遷移する際に遷移したURLの末尾にパラメーターを設定する例を紹介します。
まず、遷移先のページを作成します。
「pages」フォルダ内に「Detail.vue」ファイルを作成してください。
そしてこのファイルに下記のように記述してください。
<template>
<main>
<div class="container">
</div>
</main>
</template>
<script>
export default {
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
</style>
vue-routerをインストールしていない場合は、インストールしてください。
vue-routerについての記事か下記です。ご参照ください。
https://www.dailyupblog.com/web_development/754/
「router」フォルダ内のindex.js内に、下記のように追記してください。
import Detail from "@/pages/Detail";
import Top from "@/pages/Top";
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
export default new Router({
routes: [
{
path: "/",
name: "Top",
component: Top
},
{
path: "/detail",
name: "Detail",
component: Detail
}
]
});
Detailページをインポートして、routesに追加してください。
次はTop.vueを開いてください。
その中には下記のように記述してください。
<template>
<main>
<div>
<router-link :to="{name: 'Detail', query: {id: 1}}">記事1</router-link>
<router-link :to="{name: 'Detail', query: {id: 2}}">記事2</router-link>
<router-link :to="{name: 'Detail', query: {id: 3}}">記事3</router-link>
<router-link :to="{name: 'Detail', query: {id: 4}}">記事4</router-link>
</div>
</main>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
a {
margin-left: 10px;
}
a:first-child {
margin-left: 0;
}
</style>
Detailページへ遷移する4つのリンクを追加しました。
さて、ページ遷移する際に、URLにパラメーターをつけるには下記のように
<router-link :to="{name: 'ページ名', query: {key名: 値}}"></router-link>
と記述します。
「ページ名」には、vue-routerで設定した遷移先ページの「name」を記述します。
「query」内には「key名: 値」という形でパラメーターを記述してください。
key名はパラメーターで扱う変数名、値はこれに格納するデータです。
今回の例では、4つリンクボタンを遷移し、全て、同じDetailページに遷移するようにしますが、それぞれid値をパラメーターとして設定するように記述しました。
実際にブラウザからページを確認してみると、下記のように各ボタンクリックで遷移したページのURLの末尾にパラメーターがついていることがわかると思います。
Vueでパラメーターを取得する
さて、次はパラメーターを取得する方法です。
パラメーターを取得して、そのデータによって、ページ上に表示する情報をだしわける例を見てみましょう。
まず、例からみてみましょう。
Detail.vueを開いて、下記のように記述してください。
<template>
<main>
<div class="container">
<h2>{{ title }}</h2>
<p>{{ content }}</p>
</div>
</main>
</template>
<script>
export default {
data () {
return {
id: "",
title: "",
content: "",
detailData: [
{ id: 1, title: "記事1タイトル", content: "これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。" },
{ id: 2, title: "記事2タイトル", content: "これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。" },
{ id: 3, title: "記事3タイトル", content: "これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。" },
{ id: 4, title: "記事4タイトル", content: "これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。" }
]
}
},
created () {
this.id = this.$route.query.id;
switch (this.id) {
case 1:
this.title = this.detailData[0].title;
this.content = this.detailData[0].content;
break;
case 2:
this.title = this.detailData[1].title;
this.content = this.detailData[1].content;
break;
case 3:
this.title = this.detailData[2].title;
this.content = this.detailData[2].content;
break;
case 4:
this.title = this.detailData[3].title;
this.content = this.detailData[3].content;
break;
}
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
</style>
まず下記でパラメーターを取得できます。
this.$route.query.パラメーターkey
今回の例で見ると「this.id = this.$route.query.id;」でパラメータを取得して、変数に格納しています。
今回の例は、パラメーターを取得して、その値に応じて、表示するh2タイトルとコンテンツの内容を変える例です。
実際にTopからボタンクリックで遷移してみてください。
パラメーターのidの値によって表示される内容が変わると思います。
動的ルートマッチングとパラメーター
Vueにおいて、異なるページではあるが、同じコンポーネントを呼び出したい場合などがあると思います。
例えば、ユーザーページにて、異なるユーザーのページだが呼び出しているコンポーネントは同じ場合などです。
こういう場合、先述の例のように同じコンポーネントを呼び出すが、パラメーターで判別して、表示させる内容を変えたりします。
しかし、その際不具合が起きることがあります。
試しに、Header.vueを開き下記のように記述してください。
<template>
<header>
<div class="row">
<router-link :to="{name: 'Detail', query: {id: 1}}">記事1</router-link>
<router-link :to="{name: 'Detail', query: {id: 2}}">記事2</router-link>
<router-link :to="{name: 'Detail', query: {id: 3}}">記事3</router-link>
<router-link :to="{name: 'Detail', query: {id: 4}}">記事4</router-link>
</div>
</header>
</template>
<script>
export default {
data () {
return {
title: "ヘッダー"
}
}
}
</script>
<style scoped>
header {
padding: 1.8em 5%;
background: #778899;
}
header .row {
text-align: right;
}
header a {
color: #fff;
text-decoration: none;
margin-left: 2em;
}
header a:hover {
text-decoration: underline;
}
h1 {
margin: 0;
color: #fff;
}
</style>
すると、ヘッダーに記事1〜記事4までのリンクが設置されたと思います。
その中から一つクリックして遷移してみてください。
遷移後、再度ヘッダーのどれかの記事リンクを押してみてください。
表示内容は変わらないと思います。
動的ルートマッチングでは、パラメーターが変更されても同コンポーネント内での遷移であれば、コンポーネントを再利用する性質があります。
ただ、このようにコンポーネントを再利用した場合、ライフサイクルフックは呼び出されません。
ですので、パラメーターの変更を監視する必要があります。
解決策として、「watch」でパラメーターの変化を監視してあげます。
Detail.vueを開いて、下記のように記述してください。
<template>
<main>
<div class="container">
<h2>{{ title }}</h2>
<p>{{ content }}</p>
</div>
</main>
</template>
<script>
export default {
data () {
return {
id: "",
title: "",
content: "",
detailData: [
{ id: 1, title: "記事1タイトル", content: "これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。これは記事1の内容です。" },
{ id: 2, title: "記事2タイトル", content: "これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。これは記事2の内容です。" },
{ id: 3, title: "記事3タイトル", content: "これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。これは記事3の内容です。" },
{ id: 4, title: "記事4タイトル", content: "これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。これは記事4の内容です。" }
],
}
},
methods: {
dataDisplay: function () {
this.id = this.$route.query.id;
switch (this.id) {
case 1:
this.title = this.detailData[0].title;
this.content = this.detailData[0].content;
break;
case 2:
this.title = this.detailData[1].title;
this.content = this.detailData[1].content;
break;
case 3:
this.title = this.detailData[2].title;
this.content = this.detailData[2].content;
break;
case 4:
this.title = this.detailData[3].title;
this.content = this.detailData[3].content;
break;
}
}
},
mounted () {
this.dataDisplay();
},
watch: {
$route (to, from) {
this.dataDisplay()
}
},
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
</style>
上記にて、追記した箇所は下記部分です。
watch: {
$route (to, from) {
this.dataDisplay()
}
},
これでパラメーターの変更を監視してくれます。
中に変更時の処理を記述することで、今回の不具合は解消できます。
watch: {
$route (to, from) {
処理...
}
},
再度、ページを開いて、ヘッダーから同コンポーネント間を遷移してみてください。
問題なく、表示内容が変わっていると思います。
まとめ
今回はVueにおけるパラメーターの設定・取得方法についてまとめてみました。
パラメーターの制御はWebアプリケーション開発においてとても重要な項目です。
必須項目なので、必ず身につけておきたいところです。
それでは今回はここまで!
お疲れ様でした。
下記は動的ルートマッチングとパラメーターに関する公式のページです。
https://router.vuejs.org/ja/guide/essentials/dynamic-matching.html#%E3%83%8F%E3%82%9A%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%83%BC%E5%A4%89%E6%9B%B4%E3%81%AE%E6%A4%9C%E7%9F%A5