Edited at

Vue.jsでSPAサイトを作成するチュートリアル【2. ルーター編】

More than 1 year has passed since last update.

Vue.jsを使い始めていろいろできることが多くなってきたので、整理する意味も兼ねてチュートリアルにまとめます。

今回はコーポレートサイトを想定して作成していきます。

※記事が長くなったのでチュートリアルを分割しました。


目次


前提


  • タスクはnpm scriptsで一限管理

  • コマンドはyarnを使用


  • vue-cliwebpack-simpleを使用


バージョン


  • "vue": "^2.5.11"

  • "vue-router": "^3.0.1"

  • "webpack": "^3.6.0"


SPAサイトの全体像

今回作成するSPAサイトの全体像は以下です。


  • index

  • about

  • service

  • recruite

  • contact

ディレクトリ構成は以下です。

/pagesに各ページのディレクトリを作成し、templateとstyleとscriptを各外部ファイルとして扱います。

/src

/layouts
Default.vue
/pages
/Index
Index.vue
Index.pug
Index.scss
Index.js
/About
About.vue
About.pug
About.scss
About.js
/Service
Service.vue
Service.pug
Service.scss
Service.js
/Recruite
Recruite.vue
Recruite.pug
Recruite.scss
Recruite.js
/Contact
Contact.vue
Contact.pug
Contact.scss
Contact.js
App.vue
main.js
router.js
index.html
// 以下省略

ルーターを実装する前に動作確認用としてindexとaboutを先に作成しておきましょう。

HTMLは今回はpugを使用します。

pugを追加します。

$ yarn add -D pug

indexページを作成します。


/src/pages/Index/Index.vue

<template

lang="pug"
src="./Index.pug"
/>

<script src="./Index.js" />

<style
lang="scss"
src="./Index.scss"
scoped
/>



/src/pages/Index/Index.pug

main.main

p {{ text }}
.block
| block



/src/pages/Index/Index.js

export default {

data: function () {
return {
text: 'index'
}
}
}



/src/pages/Index/Index.scss

.block {

color: #f00;
display: flex;
}


同様にaboutページもvue, pug, js, scssの各ファイルを作成しましょう。

vueファイルのtemplateはpugで統一したいので、App.vueのtemplateもpugで書き直しておきましょう。


App.vue

<template lang="pug">

#app.app
img(src="./img/logo.png")
</template>



vue-routerの環境構築

vue-routerを追加します。

$ yarn add vue-router

ルーターファイルを追加し記述します。

/layouts/Default.vueのコンポーネントの子として各ページをchildren内に記述します。


/src/router.js

export default [

{
path: '/',
name: 'index',
component: require('./layouts/Default.vue').default,
children: [
{
path: '',
name: 'index',
component: require('./pages/Index/Index.vue').default,
},
{
path: '/about/',
name: 'about'
component: require('./pages/About/About.vue').default
}
// 省略
]
}
]


参考:ネストされたルート

main.jsを以下に差し替えます。


main.js

import Vue from 'vue'

import App from './App.vue'
import VueRouter from 'vue-router'
import Routes from './router.js'

Vue.use(VueRouter)

const router = new VueRouter({
mode: 'history',
routes: Routes
})

const app = new Vue({
router,
render:h => h(App)
}).$mount('#app');


App.vueを以下に書き換えます。


/src/App.vue

<template lang="pug">

#app.app
router-view
</template>

共通レイアウトを作成します。

$ touch src/layouts/Default.vue

Default.vueに記述します。


/src/layouts/Default.vue

<template lang="pug">

.wrap
p header
router-link(to="/") index
router-link(to="/about/") about
router-link(to="/service/") service
router-link(to="/recruite/") recruite
router-link(to="/contact/") contact
main#main.main router-view
p footer
</template>


ローカルで作業する際にbrouser-syncの以下の設定をしておくと、各URLに直接アクセスできるようになります。

参考:react-routerとbrowser-syncを利用して快適に開発するちょっとした設定

ブラウザで確認してページ遷移してindexページとaboutページがそれぞれ表示されれば成功です。

その他各ページも同様に作成していきましょう。

その際に、router.jsに各ページの指定も忘れないように追記しましょう。

遷移するか確認するためにDefault.vueのrouter-linkを追記すると良いでしょう。


ページ遷移時の表示位置を最適化

ページ遷移した時に中途半端な位置で表示することがあります。

他のページへ遷移した場合はページトップ、ブラウザの「戻る」「進む」ボタンを押すと遷移前の位置を表示するよう最適化します。


main.js

// 省略

const router = new VueRouter({
mode: 'history',
routes: Routes,
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
})
// 省略

参考:スクロールの振る舞い


まとめ

ルーターはSPAでは重要な役割を果たしていて、ページ間のやりとりに重宝します。

最近のウェブサイトはページの非同期遷移をおこなっているものが増えてきました。

積極的に取り入れてユーザー体験を向上させましょう。