Vuejs APIアクセスはcreatedとmountedのどちらで行う?

created と mounted

どちらもVuejsが提供するライフサイクルフック。たいていのサンプルでは、このライフサイクルフックのどちらかでAPIアクセスをするが、どんな違いがあるんだろう。

lifecycle

  • created
  • インスタンスの初期化が済んで props や computed にアクセスできる
  • DOMにはアクセスできない
  • mounted
  • created + DOMにアクセスできる

APIアクセスは created と mounted のどちらで行う?

APIアクセスはほとんどのライブラリで非同期に行われる。そのため、 created と mounted のどちらでAPIアクセスを開始しようが、レスポンスが返ってきた時点でコールバックが実行される。

上記を踏まえて、レスポンス完了後のコールバックの中で、

  • propsにデータを設定するだけの場合は、 created を使う
  • DOMを構築してる間にも、HTTPの通信を行えるから
  • DOMがでかいと、Edgeだと、mountedよりも体感できるレベルで早くなる
  • DOMにアクセスする必要があるときは、 mounted を使う
  • レスポンスが即返ってきた場合に、DOMの構築が終わっていない可能性がある
  • jQuery 時代をひきずったようなDOMを直接指定するライブラリを使うときはこっち

と良さそう。

検証環境

  "dependencies": {
    "axios": "^0.17.1",
    "vue": "^2.5.2"
  }

json serverを用意する

npm で json-server をインストールし、起動する。

$ json-server --watch db.json
{
  "users": [
  {
    "id": 1,
    "name": "Stark"
  },
  {
    "id": 2,
    "name": "Targaryen"
  },
  {
    "id": 3,
    "name": "Tyrell"
  }
  ]
}

サンプルを用意する

<template>
  <section>
  <h1>ユーザリスト</h1>
  <ul>
    <li v-for="user in users" :key="user.id">
    {{user.name}}
    </li>
  </ul>
  </section>
</template>

<script>
import Axios from 'axios'

export default {
  name: 'Users',
  data () {
    return { users: [] }
  },
  created () {
    const self = this
    Axios.get('http://localhost:3000/users')
    .then((res) => {
      self.users = res.data
    })
  }
}
</script>

実行結果

f:id:kimulla:20191201132519g:plain

  • mounted が実行される
  • usersが [] の状態でDOMが作られる(『ユーザリスト』のタイトルだけ先に表示される)
  • レスポンスが返ってきたら users に値が設定される
  • Vueが変更を検知してDOMが再構築される

参考