前提・実現したいこと
いつもお世話になっております。
現在vue-cli3を使い開発を行っているのですが、firebaseを用いてグーグルアカウントでログインを行いページが切り替わると、「Error in render: "RangeError: Maximum call stack size exceeded"」というエラーメッセージとともにVueが止まってしまい、v-bind
等のディレクティブが効かなくなってしまいました。
consoleを見るにエラーメッセージが無限に増えていくので、以下のコード内で「何らかの処理」が無限に繰り返されているようです。
ログイン中のみ起こっており、ログアウトするか別のページに切り替えると収まります。
原因を解明しようにも再帰関数はありませんし、Vue Devtoolsで確認しても特にコンポーネント内の関数が無限に実行されている形跡はなく、自分で見る限りでは問題を発見できませんでした。
完全に手詰まりになっています、どうか皆様お力添えをお願いいたします。
※追記
.home
と.authentication__button
の2つのclass
のv-bind
で、loginUser
を参照している事が原因かもしれません。
一つを消すと「Error in render: "RangeError: Maximum call stack size exceeded"」のメッセージ自体は出るものの、それも一度だけであり、無限ループは起きていませんでした。
2つ以上すると無限ループするのでしょうか...?
調べてもそこら辺りの情報は出てこず、結局分かりませんでした。
詳しい方、よろしければご教授お願いいたします。
該当部分のコード
※Vuexのstateから読み込んでいるloginUser
はログインした時にユーザー情報を格納する変数です。
これをclass
のv-bind
とcomputed
で参照する事でログイン・非ログイン時の表示を切り替えています。
html
1<template> 2 <section class="home" :class="{'home--logged-in': loginUser}"> 3 <div class="title"> 4 <img class="title__logo" :src="require('@/assets/images/card-background.png')"> 5 <div class="title__contents"> 6 <h1 class="title__heading">Online Book Manager</h1> 7 <h2 class="title__ruby">読書記録が保存できるオンライン本棚</h2> 8 <p class="title__description"> 9 <span v-html="usage.icon"></span> 10 {{ usage.description }} 11 </p> 12 </div> 13 </div> 14 15 <div class="authentication"> 16 <p class="authentication__sentence"> 17 <span v-html="instructions"></span> 18 </p> 19 <a 20 class="authentication__button" 21 :class="{'authentication__button--logged-in': loginUser}" 22 @click="authenticate" 23 > 24 <span v-html="authentication.icon"></span> 25 {{ authentication.processing }} 26 </a> 27 </div> 28 </section> 29</template>
※mixinで読み込んでいるauthentication
はfirebaseのログインに関する処理です。
処理自体はsweetalert2でalert
を出して、それによりfirebaseのlogin
・logout
を実行するという単純なものです。
こちらは動いていた時から弄っていないので、今回は関係ないと思い詳しくは載せていません。
JavaScript
1import { mapState } from 'vuex'; 2import { authentication } from '@/mixins/authentication'; 3 4export default { 5 name: 'home', 6 mixins: [authentication], 7 created() { 8 this.insertTag('Google'); 9 }, 10 data() { 11 return { 12 tag: '', 13 } 14 }, 15 computed: { 16 usage() { 17 if(!this.loginUser) { 18 return { 19 icon: '<i class="fas fa-arrow-circle-down"></i>', 20 description: 'アプリの利用にはログインが必要です。' 21 } 22 } else { 23 return { 24 icon: '<i class="fas fa-arrow-circle-up"></i>', 25 description: '左上のタブから本を登録できます。' 26 } 27 } 28 }, 29 instructions() { 30 return !this.loginUser ? `${this.tag}アカウントでOnline Book Managerにログインします。` : 'Online Book Managerからログアウトします。' 31 }, 32 authentication() { 33 if(!this.loginUser) { 34 return { 35 icon: '<i class="fas fa-sign-in-alt"></i>', 36 processing: 'Sign in' 37 } 38 } else { 39 return { 40 icon: '<i class="fas fa-sign-out-alt"></i>', 41 processing: 'Sign out' 42 } 43 } 44 }, 45 ...mapState(['loginUser']), 46 }, 47 methods: { 48 insertTag(word) { 49 [...word].forEach((character, index) => { 50 this.tag += `<span class="insert${++index}">${character}</span>`; 51 }) 52 }, 53 authenticate() { 54 if(!this.loginUser) { 55 this.signIn(); 56 } else { 57 this.signOut(); 58 } 59 } 60 } 61};
過去の動いていたコード
※主な違いは、マスタッシュ構文を使って表示を切り替えているか、またはv-if
を使ってそれを行っているか。
その分のcssの変更をclass
のv-bind
を使って行っているか否か、の2つです。
html
1<template> 2 <section class="home"> 3 <div class="title"> 4 <div class="title__wrapper"> 5 <h1 class="title__ruby">読書記録が保存できるオンライン本棚</h1> 6 <h1 class="title__heading">Online Book Manager</h1> 7 </div> 8 <p class="title__description"> 9 <template v-if="!loginUser"> 10 <i class="fas fa-arrow-circle-right"></i><!-- PC --> 11 <i class="fas fa-arrow-circle-down"></i><!-- スマホータブレット --> 12 アプリの利用にはログインが必要です。 13 </template> 14 <template v-else> 15 <i class="fas fa-arrow-circle-up"></i> 16 左上のタブから本を登録できます。 17 </template> 18 </p> 19 </div> 20 21 <div class="authentication"> 22 <p class="authentication__sentence"> 23 <span class="sentence-title"> 24 <template v-if="!loginUser"> 25 <span v-html="tag"><!-- Google --></span>アカウントでログイン 26 </template> 27 <template v-else> 28 ログアウト 29 </template> 30 </span> 31 <span class="sentence-description"> 32 <template v-if="!loginUser"> 33 GoogleアカウントでOnline Book Managerにログインします。 34 </template> 35 <template v-else> 36 Online Book Managerからログアウトします。 37 </template> 38 </span> 39 </p> 40 <a 41 class="authentication__login-button" 42 v-if="!loginUser" 43 @click="loginProcessing" 44 > 45 <i class="fas fa-sign-in-alt"></i> 46 LOGIN 47 </a> 48 <a 49 class="authentication__logout-button" 50 v-else 51 @click="logoutProcessing" 52 > 53 <i class="fas fa-sign-out-alt"></i> 54 LOGOUT 55 </a> 56 </div> 57 </section> 58</template>
あなたの回答
tips
プレビュー