#非同期読み込みを含むトランジション(P312)
前回の【基礎から学ぶ Vue.js】Chapter9「ネストされた複雑なページを作成しよう」の動作確認 で著者のmio様にアドバイスいただきました知識をもとに、同じくTIPがありますChapter9サポートページ「S54 ページの遷移にエフェクトを適用する」セクションの中の非同期読み込みを含むトランジションもコードを追記して動作確認してみましたので、記事にしておきます。
なお、本記事に関しましては著者様にご確認いただいたわけではなく、一応動作確認できましたレベルで素人がドヤ顔で書いているだけなので、もしかするともっと最適な方法があるのかもしれません。
##この動作確認の前提
書籍では特定のアプリケーションが指定されているわけではありませんが、Chapter9で作成しているアプリケーションに対して追記しています。そのため、まず【基礎から学ぶ Vue.js】Chapter9「ネストされた複雑なページを作成しよう」の動作確認 ができている前提(ストアルートの登録とか)です。
また学習用のため、console.logやsetTimeoutなど本来不要な動作確認用のコードを私が勝手に追記しています。
##ポイント:モジュールの登録とルーターへのストアルートの登録
とりあえずこうすると動いたよ的な報告のため、正しいのかどうか不明ですが、書籍サポートページ「S54 ページの遷移にエフェクトを適用する」のコードに以下の手順で追記しました。
- 「src/store/view.js」モジュールを「src/store.js」ファイルでストアルートに登録する
- 「src/store.js」のストアルートを「src/router.js」のルーターで読み込む
- 「src/conponents/LoadingOverlay.vue」のオーバーレイ用コンポーネントを「src/App.vue」に読み込む
##コードの具体例
具体的には以下のコードを追記しました。
(書籍のサンプルコードで使われているディレクトリ構造を踏襲した場合)
###ストアルートにview.jsモジュールを登録(src/store.js)
import Vue from 'vue'
import Vuex from 'vuex'
import product from '@/store/product.js' // 前回登録したモジュール
import view from '@/store/view.js' // 今回登録するモジュール
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
product, // 前回登録したモジュール
view, // 今回登録するモジュール
},
//...
})
###ストアルートをルーターで読み込む(src/router.js)
グローバルのナビゲーションガードでストアを使っているので、ここでストアルートを読み込みます。
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/views/Home'
import ProductList from '@/views/ProductList' // 商品一覧
import Product from '@/views/Product' // 商品情報(親ルート)
// Productの子ルートたち
import ProductHome from '@/views/Product/Home'
import ProductReview from '@/views/Product/Review'
import ProductReviewDetail from '@/views/Product/ReviewDetail'
import store from '@/store.js' // ストアルートの読み込み(今回追記のポイント)
Vue.use(VueRouter)
const router = new VueRouter({
//…以下書籍と同様なので省略
})
export default router
// 書籍にもあるフック(VueRouterインスタンス生成前ではダメ)
// ルーターナビゲーションの前にフック
router.beforeEach((to, from, next) => {
setTimeout(next, 1000) // ナビゲーションが解決するまで時間のかかるコンポーネントの例にあるやつ
store.commit('view/start')
next()
})
// ルーターナビゲーションの後にフック
router.afterEach(() => {
store.commit('view/end')
})
###オーバーレイ用コンポーネントの読み込み(src/App.vue)
Home
商品情報
<script>
// オーバーレイ用のコンポーネントを読み込む
import LoadingOverlay from '@/components/LoadingOverlay.vue'
export default {
name: "App",
components: { LoadingOverlay }, // これ忘れないようにする
};
</script>
//前セクションの「簡単なトランジション」を実装した場合以下のCSSがある状態
<style>
.view-enter-active, .view-leave-active {
transition: opacity 0.5s;
}
.view-leave-active {
position: absolute;
}
.view-enter, .view-leave-to {
opacity: 0;
}
</style>
ここまでの実装で一応動作するはずですが、以下のイメージでコンソールで動きを追っていきたかったので学習のため以下を追記しました。(こんなことしなくても何かデバッグ用のツールがあるかもしれませんが)
###デバッグツールあった
コンソールで確認しなくても、書籍でも紹介されているChromeブラウザ拡張機能のVue.js Devtoolsというデバッグツールがありました。データやストアの状態を確認できます。
というかなぜ自分はこれを使わずに学習していたのか…非常に便利!
Vue.js Devtoolsがあればconsole.logを無駄に入れまくる必要はないです。
###Loading表示確認のために時間差発生と、コンソール確認(src/store/view.js)
export default {
namespaced: true,
state: {
loading: false
},
mutations: {
start(state) {
console.log('loadingをtrueにするよー') // コンソール確認用
state.loading = true
console.log('loadingをtrueにしたよー') // コンソール確認用
},
end(state) {
console.log('loadingをfalseにするよー') // コンソール確認用
// Loading表示確認のために時間差発生させてる。実際はsetTimeoutいらない
// state.loading = false だけで良い
setTimeout(function(){state.loading = false}, 2000);
console.log('loadingをfalseにしたよー') // コンソール確認用
}
}
}
###CSSでLoading見やすくするのと、コンソール確認(src/components/LoadingOverlay.vue)
<script>
export default {
computed: {
loading() {
console.log('loadingの状態返すよー') // コンソール確認用
return this.$store.state.view.loading
}
}
}
</script>
/* Loadingを目立つように装飾(ベンダープレフィックスまでいらないかもですが一応) */
<style>
.loading {
top: 0;
position:fixed;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
background-color: #42b983;
color: #ffffff;
width: 100%;
height: 100%;
}
.loading-enter-active {
transition: all 0.25s;
}
.loading-leave-active {
transition: all 0.5s ease 0.5s; /* ルータービューが終わった後に */
}
.loading-leave-to {
opacity: 0;
}
</style>
##まとめ
以上、サポートページにてTIPを入れていただいておりましたサンプルコードの実装をしてみました。
mio様にはサポートページにリンクまで貼っていただいて大変恐縮でございます
何か恩返しになればと思いこちらも記事化してみましたが、いかんせん勉強中の初心者のため、見当違いである可能性もありますのでご了承ください
引き続き精進していきたいと思います