背景
asyncDataもfetchも、どちらも非同期にデータを外部サーバへ取りに行く処理を定義するための関数である。どちらも似たような処理ができるものの、2つ用意されているという事はそれぞれに異なる用途がある事を示す。
ここではCSR (Client-Side Rendering) の場合を考えるものとする。
asyncData と fetch の違い
asyncData は fetch より先に呼ばれる
asyncData は beforeCreate フックの手前で呼ばれる。一方で、 fetch は created の後で呼ばれる。したがって、 asyncData の中で return した値は fetch の中で利用可能だが、その逆はできないということになる。
よりわかりやすいライフサイクルの説明が公式から提供されているので、参考にされたい:


この図は クリエイティブ・コモンズ 表示 - 改変禁止 4.0 国際 ライセンスの下に提供されています。
(c) NuxtJS
fetch は this にアクセスできるが、 asyncData はできない
asyncData では this が提供されない。その代わりに、 context にアクセス可能である。だいたいのことは context で提供されるいずれかの引数でできると思われる。
結局、どんな時にどっちを使えば良いのか
asyncData は return することで、 this に値を定義することができる。一方、 fetch は data で定義した値を変更することまでしかできず、新規に定義するところまではできない。
こう見ると asyncData を使っておけば良さそうに見えるが、 Component の中では asyncData を使用できない制限があるので、その場合は fetch を使う必要がある。