Routerとは、Vueが用意しているプラグインで、URLとプロジェクトを関連付ける役割をするもの。
これによって大規模SPAなどが作れる。
Routerプラグインのセットアップ
CLIで、下記のコマンドを実行してRouterプラグインをインストール。
npm install vue-router
src直下にJSファイルを作成。良く使われる名前は、router.js
src
│ App.vue
│ main.js
│ router.js
│
├─assets
│ logo.png
│
└─components
HelloWorld.vue
router.jsの中にRouterプラグインを使用できるように設定していく。
import Vue from 'vue'; import Router from 'vue-router'; Vue.use(Router); export default new Router({ routes: [{},{}] });
関連付けをさせたいコンポーネントをインポートして、
routes: [{},{}]のオブジェクトの中に、パスとコンポネントを関連付ける。
import Vue from 'vue'; import Router from 'vue-router'; import Home from './views/Home.vue'; import Users from './views/Users.vue'; Vue.use(Router); export default new Router({ routes: [{ path: '/home', component: Home }, { path: '/users', component: Users }] });
main.jsでrouterをインポートさせる。
router.jsでRouterプラグインを使えるようにしているため、main.js上でrouter.jsをインポートする事で、vueインスタンス上で「router」が使用できるようになる。
import Vue from 'vue' import App from './App.vue' import router from './router.js' Vue.config.productionTip = false new Vue({ router, render: h => h(App), }).$mount('#app')
App.vueで<router-view>タグを使用して動的コンポーネントを表示させる。
<template> <div> <router-view></router-view> </div> </template>
RouterのURLに「#」が付く理由
従来のマルチページアプリケーションでは、それぞれのURLに対応するhtmlを用意して、アクセスをしていた。
VueRouterでは、どんなページにアクセスしてもindex.htmlを表示させる処理を行っている。この仕組みが シングルページアプリケーション(SPA)である。
「#」以降のURLを頼りに動的コンポーネントを表示させているだけであって、URLが変わってもネットワークは動かない。
ブラウザーにとって、#はidを指定する場所という認識であるため、#以降のURLが変わってもインターネットは動かない。
「#」を外す方法
router.jsの設定でmodeを追記するだけで「#」を外すことができる。
デフォルトではhashになっている。
mode:”history”
export default new Router({ mode:"history", routes: [{ path: '/home', component: Home }, { path: '/users', component: Users }] });
#を外すとURLが変わるごとにアクセスがされるが、node.jsが裏側で必ずindex.htmlを返している。
公開する時は、全てのパスにindexを返す設定を行う必要がある。
>公式サイト サーバー設定方法
aタグを使わないURLの切り替え方法
aタグを使用したリンクは、切り替える度にネットワークアクセスをしてしまう。アクセスする度、全てのJSを取得するため表示が遅くなる。
SPAのように通信をせずに動的コンポーネントを切り替える場合は、<router-link>タグを使用する。
<nav> <router-link to="/home">Home</router-link> <router-link to="/users">Users</router-link> </nav>
router-linkは、ソース表示するタグを指定することもできる。
※デフォルトaタグ表示
<router-link to="/home" tag="div">Home</router-link>
to属性をv-bindを使って動的にする
URLを指定するto属性を動的にするには、v-bind(省略型[:])を用いる。
<router-link :to="'/home/' + (Number(id) + 1)">次のページ</router-link>
数値として演算を行う場合、要素がすべてString型になってしまうので、Number型にキャストする必要がある。
toの値をオブジェクトにする
nameをつかって、パスルートに任意の名称を付ける。
name:”users-age”
export default new Router({ routes: [{ path: '/users/:id', component: Users, props: true, children: [{ path: 'name', component: UsersName }, { path: 'age', component: UsersAge, name:"users-age"}] }] });
toでnameを使ってパスルートを指定する。
<router-link :to="{name:'users-age'>次のページ</router-link>
~/id/のパラメータ情報をパスに含みたい時、paramsをオブジェクトに追加することができる。
<router-link :to="{name:'users-age',params:{id:Number(id)+1}}">次のページ</router-link>
queryもパラメータと同じようにオブジェクトに入れる事ができる。
queryとは、URLで?や=で表現されるもの。
<router-link :to="{name:'users-age',params:{id:Number(id)+1},query:{lang:'ja'}}">次のページ</router-link>
activeなリンクを取得する
active-class属性を付与することで、現在アクティブなリンクをつかむことができる。 toで指定したパスを表示している時に有効になる。
<nav> <router-link to="/home" tag="div" active-class="active">Home</router-link> <router-link to="/users" active-class="active">Users</router-link> </nav> <style scoped> .active{ color: red; } </style>
/homeを例にとると、/home/123456など、homeの子階層を表示している場合もhomeがアクティブになる。/homeのみアクティブにし、子階層を表示している時は非アクティブにしたい場合、exact属性を付与する。
exact属性は、toで指定しているURLとイコールの時しかアクティブにならない命令を与える事ができる。
<router-link to="/home" tag="div" active-class="active" exact>Home</router-link>
JavaScriptからURLを切り替える
イベントでURLを切り替えることもできる。
$routerはナビゲーションで用いられる。URLを切り替えたり等。情報を取得する時に用いる$routeと混在しないように注意する。
<template> <div> <h1>Home</h1> <button @click="toUsers">Usersページへ移動する</button> </div> </template> <script> export default { methods: { toUsers() { this.$router.push({ path: "users" }); } } }; </script>
動的URLを作る
/users/idのようなURLを作るには、router.jsに動的となるキーを設定する。
コロンで繋げて書く。
/users/:id
routes:[{ path: '/users/:id', component: Users }]
<メモ>
アクセスしたidの値(パラメータ)を確認するコード
<template> <div> <h1>Users</h1> <p>id:{{$route.params.id}}</p> </div> </template>
動的URLは、ライフサイクルフックが生成されない。
watchを使って、変化を取得する。
export default { watch:{ $route(to,from){ // eslint-disable-next-line no-console console.log(to); // eslint-disable-next-line no-console console.log(from); } } };
動的URLのルートはpropsを使って下記のように汎用性を持たせることが可能。
,props:true
routes: [{ path: '/users/:id', component: Users,props:true }]
export default { props:["id"] };
パラメータを表示する場所では、propsの値を{{}}に代入するだけ。
<p>id:{{id}}</p>
子コンポーネントの中に router-view を作る
子コンポーネントの中にRouterを設ける時は、childrenを使用する。
Routerを使いたいコンポーネントのroutesにchildrenを作り、その中でまたパスとコンポーネントの紐づけを指定する。
export default new Router({ routes: [{ path: '/users/:id', component: Users, props: true, children: [{ path: 'name', component: UsersName }, { path: 'age', component: UsersAge }] }] });