あしあと

自分自身のログ(足跡)となります。ソフトウェアエンジニアです。ブログはテック系の内容が少し多めです。

Vue.jsでdataの追加が反映されない時の対応

少し悩んだので、まとめておきます。

環境

Electronの開発でVue.jsを利用しています。
Vue.jsは使い始めて1週間程度です。

  • electron ... 4.2.2
  • vue.js ... 2.6.10

状況

Vue.jsで以下のようなコードを書きました。
実際のソースコードを載せることができないため、サンプルコードです。

new Vue({
  el: '#app',
  data: function () {
    return {
      memo: '',
      memoLis: {}
    }
  },
  methods: {
    save: function() {
      let self = this;
      pouchDb.add(this.memo).then(function (response) {
        self.memoList[response.id] = {
          'id': response.id,
          'title': self.memo
        }
      });
    }
  }
}

データの扱いとしては、

  • memo ... 入力項目
  • memoList ... 入力した項目一覧(画面上に表示)

処理としては、

  1. UI(画面)で入力し、保存を押す
  2. save関数の処理に入り、pouchDbインスタンスのadd関数を呼ぶ(非同期処理)
  3. 完了後(then)、memoListに追加

となります。

しかし、追加時にデータが反映されませんでした。

デバッグすると、memoList自体には入っていることは確認できました。
そのため、画面に描画されない課題がありました。

解決方法

オブジェクトに値を入れている部分をsetに変更します。

new Vue({
  el: '#app',
  data: function () {
    return {
      memo: '',
      memoLis: {}
    }
  },
  methods: {
    save: function() {
      let self = this;
      pouchDb.add(this.memo).then(function (response) {
        // -- 変更前 --
        // self.memoList[response.id] = {
        //   'id': response.id,
        //   'title': self.memo
        // }
        // -- 変更後 --
        self.$set(self.memoList, response.id, {'id': response.id,'title': self.memo});
      });
    }
  }
}

参考にしたサイト

最初に以下の内容を読み、nextTickが必要なのか、と考え、何通りか試しました。

qiita.com

ただ、現状のレベルでは分からず、別の方法も模索しました。
最終的には、以下の内容を参考にさせていただきました。

ti-tomo-knowledge.hatenablog.com

ちなみに、公式ドキュメントの説明は以下になります。

jp.vuejs.org

変更の追跡方法についても書いています。
このページは何度か読んだのですが、他の記事を読んだ上で再度読み直すと分かるようになりました。。。

個人的なオススメとしては、公式ドキュメントを読み、不明な点はブログ記事を読み、最終的に公式ドキュメンを読むのが良さそうです。

補足

ソースコード内で、let self = this; としています。
thenの処理でVueオブジェクトの値を変更したかったためです。
then以降は関数を定義しており、すでにthisが定義されているため、外側(Vueオブジェクト側)のthisにアクセスできないためです。