Nuxt.js初心者が「data return」など「export default」の中身をちょっとだけ理解した話

シェアする:

この記事をおすすめしたい人

  • WordPressしか知らないのにNuxt.jsを始めようとしてる人
  • export defaultの中に何を書いていいか分からない人
  • data returnの意味が分からない人
  • computedとmethodsの違いが分からない人
  • つまりオレ

何も知らない超初心者が脱WordPressしたくてNuxt.jsでサイト構築していくシリーズです。

ひとまずNuxt.jsで作ったサイトを公開しました。

僕ほどJavaScriptに理解のない状態でいきなり「Nuxt.jsでサイト作ったろ!」なんて考えるアホ人がどれほどいるかは分かりませんが、僕にとって最大の鬼門はまさにJavaScriptの部分でした。

いろんなサンプル見てるとVueファイル内に、<template><script><style>と3つの領域があって、<template>はHTMLを書く部分、<style>はCSSを書く部分です。

残った<script>の部分。

ここに何が書いてあるかさっぱり分からないんです。

という状態からなんとなく思った通りに書けるようになるまでで学んだお話をしたいと思います。

WordPressの上でな!

※ このブログはWordPress製ですが、Nuxt.jsに移行予定です

まずは<script>の項目を列挙

僕がなんとなく扱えるようになったのが以下の7つです。


export default {
  layout: 'XXXXXXXXX',
  head() {
    return {
    }
  },
  data() {
    return {
    }
  },
  asyncData ({ app }) {
  },
  mounted() {
  },
  computed: {
  },
  methods: {
  },
}

最初の「export default」の部分はまだ勉強していませんが、分からなくてもとりあえず動いているので後回しにします。

その中身。

ここにはどうもVue.jsNuxt.jsの機能が含まれているようで、けっこう種類豊富です。 7つではまだ全然足りていないです。

勉強にあたっては、サンプルを見て「これを使えばやりたいことができそう」とあたりを付けて、マニュアルを読んで、実際に動かしてーっとやっていった感じでやっていきました。 その過程で得た「初心者にはこう表現した方が分かりやすい」みたいな僕の理解を説明していきます。

「layout」については説明するまでもない内容なので、レイアウトの記事を読んでください。 残りの6つをいきます。

headメソッド

headメソッドはnuxt.config.jsで設定したheadに、要素を追加したり、内容を上書きしたりする際に使います。

returnとなっていて関数っぽいですが、ページ内でいちいちコールする必要はありません。 勝手に実行されます。

僕はここでページタイトル、description、OGPのタイトルとdescriptionの上書きをしています。


head() {
  const title = 'ページのタイトル'
  const desc = 'ページの説明'
  return {
    title: title,
    meta: [
      { hid: 'description', name: 'description', content: desc },
      { hid: 'og:title', property: 'og:title', content: title },
      { hid: 'og:description', property: 'og:description', content: desc },
    ]
  }
},

returnの前なら、上のように変数を作ったり、計算させたりすることができます。 Nuxt.js公式マニュアルにもある通り、「this」でその他の変数にアクセスすることもできます。

詳細についてはページ毎にタイトルを設定する記事canonicalを設定する記事を見てください。

dataメソッド

dataメソッドはVue.jsの機能です。

これがもう、理解しにくいなんてもんじゃなかったです。

head同様にreturnが付いているので余計に分かりにくくなっている気がするんですが、要はこいつ、

ただの変数宣言です!

本来ならこう↓書きたくなるところを、


var title = 'ページのタイトル'
var desc = 'ページの説明'
var child = []

Vue.js(Nuxt.js)ではこう↓書いているだけです。


data() {
  return {
    title: 'ページのタイトル',
    desc: 'ページの説明',
    child: [],
  }
},

ひとつ注意しないといけないのは、ページ内で使いまわす変数(関数内でのみ使う変数を除く)は先に全部ここで宣言しておかなければならないんです。 上のtitleやdescのように初期値を代入する場合だけではありません。 childのように空なら空で設定しないといけない。

例外的に次のasyncDataで返す変数は宣言しなくていいみたいです。 実行時にdataとasyncDataの戻り値を合わせて、変数になります。

dataで宣言した変数へのアクセス方法

<template>内からは「title」「{{title}}」のようにそのままアクセスします。

<script>内からは「this.title」のようにアクセスします。

asyncDataメソッド

Nuxt.jsには処理の呼ばれる順番【ライフサイクル】というのがあるみたいで、asyncDataの説明見ていてもかなり理解しにくかったんですが、僕はこれを…

コンストラクタと理解しました。

要はページ内の処理が始まる前の【前処理】ですね。

もうちょっと正確に言うと、「コンストラクタの前に呼ばれるコンストラクタ」みたいなイメージで、asyncDataからはインスタンス(this)にアクセスできません。

今回作ったサイトでは、もっぱらデータベースとの接続に使っています。

ページ内で使うデータを先にデータベースから引っ張ってきておいて、ページ内で使う変数に格納しておくわけです。

同様の処理は次の「mounted」でもできますが、mountedで処理すると静的出力した際に該当部分がすっからかんになってしまいます。 これはおそらく先ほどのライフサイクルの順番が影響しているんでしょう。

asyncDataはかなり事前に呼ばれているみたいです。

asyncDataの引数

これもかなり難解でした。

というのも、いろいろなサンプルを見ていると、引数に「context」と書いてあったり、「{ app }」「{ app, isDev }」と書いてあったりするからです。 定義済みの関数なのになんでこんな引数が自由自在なのか全く意味が分かりませんでした。

Nuxt.js公式によると、引数はcontextというオブジェクトでのようです。

引数が「context」の場合はcontextオブジェクトをそのまま受け取ります。 「{ app }」「{ app, isDev }」のような形の場合は、contextオブジェクトの要素にある「app」や「isDev」を展開して受け取っているようです。 任意の要素を明示して受け取れるというのか…。

まぁ、なんとなく理解できました。

contextの子要素に何があるのかはマニュアルを見てください。

asyncDataの戻り値

これはページのインスタンス(this)が受け取るとでも言えばいいのでしょうか。

dataメソッドと同じく「this」からアクセスできる変数に勝手に格納されます。

下のようなasyncDataだった場合には、


async asyncData ({ app }) {
  (略)
  
  return {
    title: value1, 
    desc: value2
  }
},

「this.title」でvalue1の中身に、「this.desc」でvalue2の中身にアクセスできます。

dataメソッドでも書きましたが、asyncDataで定義する変数は、dataメソッドで宣言する必要がありません。 宣言してもエラーにはなりません。 asyncDataの内容が優先されるっぽいです。

mountedメソッド

asyncDataと同じく「コンストラクタ」と理解しました。

こちらは本当にコンストラクタのような順番で処理が始まるようで、インスタンス(this)へのアクセス可能ですし、asyncDataのように値を返す必要もありません。

本当にコンストラクタっぽい挙動です。

ただ、こちらは「this」へアクセスできるメリットがある代わりに、ここでの処理はページ生成後に行われます。

つまり、静的出力の場合、ここでの処理がHTMLに反映されないです。 ページを開いた後に動的に処理されます。

SEOを意識してHTMLにしっかりコンテンツを埋め込んでおきたい場合はasyncDataで処理すべきなのでしょう。

mountedで処理したデータの保存はどうすれば?

mountedはthisへアクセスできるので、dataメソッドで変数を宣言しておいてそこへ放り込んでやればいいです。

例えば、dataメソッドで「title」を宣言しておき、mountedではこの↓ように処理を終えます。


this.title = 'このページのタイトル'

後は「this.title」から設定した値にアクセス可能です。

mountedの引数は?

たぶん引数はないんじゃないかと思います。

ですがthisへアクセスできるので、そこから必要なデータへアクセスできるようにすればたいがいのデータには触れると思います。

computedプロパティ

computedと次のmethodsは似ていて、ページ内からアクセスする関数を宣言する場所です。

こんな↓風に書きます。


computed: {
  testFunc() {
    (略)
    return value
  },
},

関数と言いながら計算結果がキャッシュされるそうです。

詳しくは後で書きます。

computedへのアクセス方法

上の例だと「this.testFunc」でアクセスできます。 methodsと違い、「testFunc()」のようにカッコが必要ありません。

<template>内からアクセスする場合は「testFunc」のみです。

methodsプロパティ

computedと違い、コールされるごとに毎回計算されるので、こっちの方がいわゆる関数です。

書き方はcomputedと同じで、こんな↓風に書きます。


methods: {
  testFunc(args) {
    (略)
    return value
  },
},

アクセスする場合は、「const result = this.testFunc(10)」のようにアクセスします。

computedとmethodsとの違いは?

Vue.jsのマニュアルによると、computedは計算結果がキャッシュされるそうです。

VB.netとかC#を知ってる人には、

FunctionじゃなくてProperty!

という表現が理解しやすいんじゃないかと思います。

computedはmethodsと同様に引数を持つこともできますが、引数を元に計算させて値を返させるんじゃなくて、引数を元に値をセットするだけのようです。 セットの際も「this.testFunc(10)」のようにするのではなく、この↓ように書きます。


this.testFunc = 10

.net分からない人には、「計算つき変数」みたいなイメージになるんでしょうか。

で、この結果がキャッシュに保持されているので、新たにセットしたり参照している値に変更がない限りは戻り値の再計算をすることがありません。 重い処理をさせる場合や、何度も計算させる場合には特に有効でしょう。

僕の作ったページで具体例を示します。

FF11知らない人にはピンとこないと思うのであまりいいサンプルではないですが、僕が最初に書いた動的処理を例に考えてみます。 INPUTからの入力を受けて武器ごとの攻撃力を動的に計算するアプリです。

INPUTタグでの入力値はdataで宣言した変数に格納されるだけなので、computedでもmethodsでもありません。
(これはV-modelと呼ばれるやつで、次かその次の記事で書きます)

テーブル内での計算は、大雑把に「素手の攻撃力+武器の攻撃力=実際の攻撃力」のように計算していて、素手の攻撃力は「格闘スキルに対して一定の値」、武器の攻撃力は武器ごとに固定となっています。

「素手の攻撃力」は格闘スキルの入力が変わらない限り一定なのでcomputedが適していると思われます。 もしmethodsにしてしまうと、各武器を計算するごとに毎回計算されてしまいます。
(武器が100個なら100回同じ計算をするが、computedだと1回)

これに対して、各武器の攻撃力は武器ごとに計算する必要があり、武器ごとに攻撃力の数値が違うので、キャッシュしておく必要がありません。

こういう場合はmethodsが適しているでしょう。

…分かりにくいか。

まとめ

僕が使えるようになった<script>内の7項目について初心者目線でまとめてみました。

export defaultに書ける項目はVue.jsにもNuxt.jsもまだまだありますが、この7項目を覚えた時点で、今のところ書きたい内容が全て書けるようになっています。

僕と似たような境遇の人がいたら、とりあえずこの7項目を覚えてみて、まずはNuxt.jsで思った動作が書ける実感を持ってもらえると嬉しいです。

書きたいものが書けるようになるとめちゃくちゃ楽しいですよ!

以上、WordPressからお届けしました!

シェアする: