【VueJS】transitionとrouterでページ遷移時のアニメーションをつける方法

vueJSでページ遷移をいい感じにしたい時、transitionが便利かと思います。

今回は簡単なtransitionとrouterを使って簡単なページ遷移のアニメーションをつけたのでメモしておきます。

僕自身もそうですが、vueJSをおさわりし始めた方・初心者の方は是非一緒に手を動かしながらやってみてください〜^ ^


Vue CLIで始める

vue -Vでバージョン確認

*バージョンが古い場合、vue cli 3.0~のクイックスタート

npm install -g @vue/cli
もしくは
yarn global add @vue/cli

vue cli 3.0~がすでに入っている人

vue create router-transition

*vue cliのバージョンは3.0.0以上(それ以外はvue init)
vue cliが3.0以降でないとvue createが使えない

Vue CLI v3.0.0-beta.11
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint) 
  Manually select features 

Manually select featuresを矢印キーで選択しエンター

? Check the features needed for your project: (Press <space> to select, <a> to t
oggle all, <i> to invert selection)
❯◯ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◉ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

こんな感じでどのfeatureが必要か聞かれるので、「スペースで選択」、「aで全部トグル」、「iで選択しているものとしていないものを反転」

今回はrouterのみ選択しエンター

? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arro
w keys)
❯ In dedicated config files 
  In package.json 

configファイルをどこに設置したいか聞かれるので、これも矢印キーで選択しエンター

In dedicated config files : 専用のconfigファイル
In package.json:そのままpackage.jsonファイルの中
? Save this as a preset for future projects? (y/N) 

プリセットとして保存するかい?
今回はしませんので、nを入力してエンターするとプロジェクトが作成されます。

🎉  Successfully created project router-transition.
👉  Get started with the following commands:
 $ cd router-transition
 $ yarn serve

こんな感じ

cdでフォルダに移動して、yarn serveでlocalホストを立ち上げます。
*yarnをインストールしててくださいね

こうなったらオッケーです

テキストエディタでプロジェクトフォルダを開きます。

構造はこんな感じになっているかと思います。

router-transition
    node_modules
    public
    src
        - assets
        - components
            - HelloWorld.vue
        - views
            - About.vue
            - Home.vue
        App.vue
        main.js
        router.js
    .gitignore
    .postcssrc.js
    .package.json
    yarn.lock

さて色々不要なものを消して、編集していきましょう〜

HelloWorld.vue

とりあえず今回は使わないのでdivの中身を全部削除します〜

<template>
<div class="hello">

</div>
</template>

<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

About.vue

classにpageを追加してあげます

<template>
<div class="about page">
<h1>This is an about page</h1>
<p>ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。ここはAboutページやで〜〜。</p>
</div>
</template>

Home.vue

とりあえずAbout.vueと同じにします。

<template>
<div class="home page">
<h1>This is a Home page</h1>
<p>ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。ここはHomeページやで〜〜。</p>
</div>
</template>

今の状態はこんな感じ

App.vue

ちょっとstyleタグ内で少しスタイリングしときます

<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>

<style>
body {
background: #eee;
}

#app {
margin: 0 auto;
max-width: 1000px;
background: #fff;
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
padding: 30px;
}
#nav {
padding: 30px;
}

#nav a {
font-weight: bold;
color: #2c3e50;
}

#nav a.router-link-exact-active {
color: #42b983;
}
</style>

transitionがちゃんとできればいいのであまりスタイリングは変えてません。

とりあえずこんな感じ

ではtransitionを使ってページ遷移の動きをつけていきます。

App.vue

コメントで少し説明書いてます。

<template>
<div id="app">
<div id="nav">
<!-- 以下はHTMLのaタグみたいな感じです -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>

<!-- transitionタグで囲むことでrouter animationを簡単につけれます -->
<!-- animate cssのような第三者のアニメーションライブラリも以下(enter-active-class)のように使えます -->
<transition name="router-transition" enter-active-class=“animated zoomIn
">

<!-- router-viewにviewsフォルダ内の〇〇.vueがpathに応じて表示されます -->
<router-view/>

</transition>
</div>
</template>

<style>
@import "https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.css";

body {
background: #eee;
}

#app {
margin: 0 auto;
max-width: 1000px;
background: #fff;
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
padding: 30px;
}
#nav {
padding: 30px;
}

#nav a {
font-weight: bold;
color: #2c3e50;
}

#nav a.router-link-exact-active {
color: #42b983;
}
</style>

transitionの使い方については公式ページに詳しく書いていますのでご確認ください〜
Enter/Leave とトランジション一覧

コメントでも少し書いていますが、router-linkはaタグみたいなもので、to=“ここにパス”を書きます。

そしてそのパスになったらrouter-viewがパスに応じてこの場合Home.vueかAbout.vueを表示します。

その辺はrouter.jsで編集しますが今回は割愛します。

ちなみに現在のrouter.jsの設定はこんな感じです
*とりあえず今回はノータッチなので飛ばして構いません

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
}
]
})

結構簡単ですね
nuxtJSだとルーティングなどをやってくれるみたいなのでnuxtいいですね〜〜もっと勉強しなきゃ!

さて本題に戻って、transitionの使い方ですが今回はAnimate.cssというライブラリを利用しています。
Animate.css

いっぱい使えるアニメーションがあるのでチェックしてみてください〜〜〜

これを使うには、まずAnimate.cssをCDNで読み込みます。
Animate.css(CDN)

今回はstyleタグ内で@importで読み込んでいます。

そしてtransitionタグ内に以下を追加することで使えるようになります。

enter-class
enter-active-class
enter-to-class (2.1.8 以降のみ)
leave-class
leave-active-class
leave-to-class (2.1.8 以降のみ)

今回の設定は<transition name="router-transition" enter-active-class="animated zoomIn">です

こんな感じになります。

enter-active-classしかつけてないのでコンテンツがenterする時(入ってくる時)にしか指定したアニメーションはされません

leave-active-classを追加してコンテンツがleaveする時(出て行く時)にもアニメーションをつけてみましょう〜

App.vue

<transition name="router-transition" enter-active-class="animated zoomIn" leave-active-class="animated bounceOutRight">

するとこんな感じでキモくなります笑

色々方法あるかと思いますが、今回はposition: fixed;で無理くり変えてみます笑

App.vue

<template>
<div id="app">
<div id="nav">
<!-- 以下はHTMLのaタグみたいな感じです -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>

<!-- transitionタグで囲むことでrouter animationを簡単につけれます -->
<!-- animate cssのような第三者のアニメーションライブラリも以下(enter-active-class)のように使えます -->
<transition name="router-transition" enter-active-class="animated zoomIn" leave-active-class="animated bounceOutRight">

<!-- router-viewにviewsフォルダ内の〇〇.vueがpathに応じて表示されます -->
<router-view/>

</transition>

</div>
</template>

<style>
@import "https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.css";

body {
background: #eee;
}

#app {
height: 50vh;
margin: 0 auto;
background: #fff;
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
padding: 30px;
}
#nav {
padding: 30px;
}

#nav a {
font-weight: bold;
color: #2c3e50;
}

#nav a.router-link-exact-active {
color: #42b983;
}

.page {
position: fixed; 
right: 0;
left: 0;
width: inherit;
padding: 0 50px;
}

</style>

するとこんな感じ

Animate.cssを使いたくない時

vueのtransitionタグを使うことで、cssのkeyframesでアニメーションをつけることが出来ます。

animate.css関連のものを全部削除して試してみます〜

App.vue

<template>
<div id="app">
<div id="nav">
<!-- 以下はHTMLのaタグみたいな感じです -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>

<!-- transitionタグで囲むことでrouter animationを簡単につけれます -->
<!-- nameに好きな名前をつけてstyle内のトランジションクラスの前に書きます -->
<transition name="router-transition">

<!-- router-viewにviewsフォルダ内の〇〇.vueがpathに応じて表示されます -->
<router-view/>

</transition>

</div>
</template>

<style>
@import "https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.css";

body {
background: #eee;
}

#app {
height: 50vh;
margin: 0 auto;
background: #fff;
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
padding: 30px;
}
#nav {
padding: 30px;
}

#nav a {
font-weight: bold;
color: #2c3e50;
}

#nav a.router-link-exact-active {
color: #42b983;
}

.page {
position: fixed;
left: 0;
right: 0;
width: inherit;
padding: 0 50px;
}

.router-transition-enter-active {
animation: fadeIn 1s;
animation-delay: .5s;
opacity: 0;
}

@keyframes fadeIn {
from {
transform: translateY(-20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}

.router-transition-leave-active {
animation: fadeOut 1s;
}

@keyframes fadeOut {
from {
transform: translateY(0);
}
to {
transform: translateY(-20px);
opacity: 0;
}
}

</style>

するとこんな感じ

animation-delayをかけないとこんな感じになります

お好きなようにカスタマイズしてみてください〜

詳しくは公式ページに載っているのでよく読んで色々試してみると早いです〜

では以上です〜〜〜



Posted

in