LoginSignup
0
0

More than 3 years have passed since last update.

Vue.jsで上手く初期表示が出来なかったときの謎を再レンダリングで無理やり解決した

Posted at

Vue.jsとFirebaseを利用して、Cloud Firestore からデータを読み込んで初期表示させたかったが、上手く初期表示できず苦しんだのでメモ。

事象

データベース(Firebase)から取得したデータを、Vue.jsの"Test[0]"と"Test[1]"に入れて表示させたかったが、何故か表示がされなかった。コンソールで見るとちゃんとデータは取得出来ているのに、、謎。
image.png

取り敢えずv-ifのレンダリングで無理やり解決させた。データベースに保存した内容が表示される。
image.png

v-ifの再レンダリングで無理やり解決したコード

無理やり解決させた時の全体コードを書いておく。(あまり良くない解決の仕方ではあると思う。)

.html
<!DOCTYPE html>
<html lang="jp" >
<head>
  <meta charset="UTF-8">
  <title>Vuejs Rerender</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <!-- 全体をVue.js有効にする -->
  <div id="app" v-if="Show === 1">
    <input v-model="Test[0]">
    <input v-model="Test[1]">
  </div>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/firebase/8.0.1/firebase.js'></script>
  <script>
    // Your web app's Firebase configuration
    var firebaseConfig = {
      apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      authDomain: "xxxx.firebaseapp.com",
      databaseURL: "https://xxxx.firebaseio.com",
      projectId: "xxxx",
      storageBucket: "xxxx.appspot.com",
      messagingSenderId: "999999999999",
      appId: "1:999999999999:web:xxxxxxxxxxxxxxxxxxxxxx"
    };

    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
    const db = firebase.firestore();

    const app = new Vue({
      el: '#app', // Vueが管理する一番外側のDOM要素
      data: {
        // Vue内部で利用する変数定義
        Test: ["0000","1111"],
        Show: 0,  // 再レンダリング用
      },

      created: async function (){
        // Firebaseから初期値を読み込み
        await this.FirebaseSet();
        console.log(`Test[0]:${this.Test[0]},Test[1]:${this.Test[1]}`);
        // 上手いこと初期表示できないから無理やりレンダリング
        this.Show = 1;
      },

      methods: {
        // 関数はココに記述
        FirebaseSet: async function() {
          // CloudFirestoreからデータ取得
          let docRef = db.collection("hpcaccede").doc("User01");
          let me = this;  // thisを関数内で使えないので変数に代入

          await docRef.get().then(function(doc) {
            if (doc.exists) {
              me.Test[0] = doc.data().test1;
              me.Test[1] = doc.data().test2;
            } else {
              console.log("No such Cloud Firestore document!");
            }
          });
        },
      },
    });
  </script>
</body>
</html>

ポイント

全体に対して、v-ifで再レンダリングさせる。

.html
<div id="app" v-if="Show === 1">

"Show"変数の初期値は"0"として非表示。

.js
const app = new Vue({
  el: '#app',
  data: {
   Test: ["0000","1111"],
   Show: 0,  // 再レンダリング用
  },});

"created"の最後に"this.Show"を"1"に更新して、再レンダリングさせる。

.js
created: async function (){
  await this.FirebaseSet();
  console.log(`Test[0]:${this.Test[0]},Test[1]:${this.Test[1]}`);
  // 上手いこと初期表示できないから無理やりレンダリング
  this.Show = 1;
},

原因と思われる個所を特定した

色々切り分けていくと、配列が悪さをしているっぽいことが判明。
vue.jsのルールなのか、私の書き方が悪いのかは知らんけど、Test配列を止めたら再レンダリングせずに上手く表示できた。(body要素内だけ記述しておく。)

.html
<body>
  <!-- 全体をVue.js有効にする -->
  <div id="app">
    <input v-model="Test0">
    <input v-model="Test1">
  </div>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/firebase/8.0.1/firebase.js'></script>
  <script>
    // Your web app's Firebase configuration
    var firebaseConfig = {
      apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      authDomain: "xxxx.firebaseapp.com",
      databaseURL: "https://xxxx.firebaseio.com",
      projectId: "xxxx",
      storageBucket: "xxxx.appspot.com",
      messagingSenderId: "999999999999",
      appId: "1:999999999999:web:xxxxxxxxxxxxxxxxxxxxxx"
    };

    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
    const db = firebase.firestore();

    const app = new Vue({
      el: '#app', // Vueが管理する一番外側のDOM要素
      data: {
        // Vue内部で利用する変数定義
        Test0: "0000",
        Test1: "1111",
        //Show: 0,  // 再レンダリング用
      },

      created: async function (){
        // Firebaseから初期値を読み込み
        await this.FirebaseSet();
        //console.log(`Test[0]:${this.Test[0]},Test[1]:${this.Test[1]}`);
        console.log(`Test0:${this.Test0},Test1:${this.Test1}`);
        // 上手いこと初期表示できないから無理やりレンダリング
        // this.Show = 1;
      },

      methods: {
        // 関数はココに記述
        FirebaseSet: async function() {
          // CloudFirestoreからデータ取得
          let docRef = db.collection("hpcaccede").doc("User01");
          let me = this;  // thisを関数内で使えないので変数に代入

          await docRef.get().then(function(doc) {
            if (doc.exists) {
              // me.Test[0] = doc.data().test1;
              // me.Test[1] = doc.data().test2;
              me.Test0 = doc.data().test1;
              me.Test1 = doc.data().test2;
            } else {
              console.log("No such Cloud Firestore document!");
            }
          });
        },
      },
    });
  </script>

</body>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0