社内の人に知っておいてほしいNuxtのヒントあれこれ

Tips集です。
最近私自身が分からなくて調べたり、社内の人から「これってどうやるの？」と聞かれたものを集めました。
大した話はしていません。誰かのヒントになれば幸いです。
なお、以下はSPAでの使用を想定しています。

# filterの使い方
「APIから受け取ったこの数値、三桁ごとにカンマを付けたいな……」
「そうだ、受け取った値をcomputedで加工して表示させよう！」
**ちょっとまった！**
もっと簡単な方法があるのです。

```JavaScript:/nuxt/filters/index.vue
Vue.filter('setDelimiter', function (value) {
  return String(value).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
})
```

```JavaScript:/nuxt/nuxt.config.js
module.exports = {
  plugins: [
    '@/filters'
  ]
}
```

```Vue:/nuxt/pages/hogehoge.vue
<template>
  <div>
    {{ nanikaNoSuuchi | setDelimiter }}
  </div>
</template>
```

filterを使用すれば元の値に触れることなく＆computedで新たなプロパティを宣言することなく取得した値を加工できます。
他にも、表示する文字列を任意の文字数で切りたい場合や、「YYYY-MM-DD」の形で受け取った日付を「YYYY/MM/DD」へ加工することも容易です。

```JavaScript:/nuxt/filters/index.vue
Vue.filter('dateFormat', function (val) {
  if (val) {
    return moment(val).format('YYYY/MM/DD')
  }
})
```

# pluginを使いたい
上の項目で何気なくmomentを使っていますが、使用する場合は設定が必要です。

`npm i vue-moment -D`した後、以下のファイルを作成します。

```JavaScript:/nuxt/plugins/moment.js
import Vue from 'vue'
import moment from 'vue-moment'
Vue.use(moment)
```

そしてfiltersと同様に、nuxt.config.jsに登録します。

```JavaScript:/nuxt/nuxt.config.js
module.exports = {
  plugins: [
    '@/filters',
    '@/plugins/moment' //new!
  ]
}
```

これで各コンポーネントでmomentが使用できるようになります。

```Vue:/nuxt/pages/hogehoge.vue
<template>
  <div>
    {{ $moment(fuga).format('YYYY/MM/DD') }}
    {{ piyo }}
  </div>
</template>
<script>
  import { mapGetters } from 'vuex'
  computed: {
    ...mapGetters('hoge', {
      fuga: 'getFuga'
    }),
    piyo () {
      return this.$moment(fuga).format('YYYY-MM-DD')
    }
  }
</script>
```

プラグインに対して設定が必要な場合は、plugins/hoge.js内に記述します。
例としてveeValidateの場合は次のようになります。

```JavaScript:/nuxt/plugins/vee-validate.js
import Vue from 'vue'
import VeeValidate, { Validator } from 'vee-validate'
import dictionary from '@/validate/dictionary.json' // 多言語化の際に読み込むファイル

Validator.localize(dictionary)

// バリデーションのパターン追加
const tel = {
  validate(val){
    let pattern = /^[\s0-9-+]+$/
    return pattern.test(val)
  }
}
Validator.extend('tel',tel)

Vue.use(VeeValidate, Validator)
```

## webpackのpluginは？

こっちに書きます（例としてlodash）。
pluginsへのファイル追加は不要です。

```JavaScript:/nuxt/nuxt.config.js
module.exports = {
  build: [
    plugins: [
      new webpack.ProvidePlugin({
        '_': 'lodash'
      })
    ]
  ]
}
```

# middlewareを使いたい
middlewareとはなんぞや？　→　全ページ共通でレンダリング前にやりたい処理を実行できます。

middlewareの場合も次のようなファイルを作成します。

```JavaScript:/nuxt/middleware/neko.js
export default function ({ params }) {
  console.log('にゃんこが' + params.catNum + '匹')
}
```

例が思いつきませんでした。
paramsはrouteのparamsを見ています。他にrouteやstore、form（遷移前のページ）なども取れます。
ファイルを作成したら今度もnuxt.config.jsに登録します。

```JavaScript:/nuxt/nuxt.config.js
module.exports = {
  router: {
    middleware: [
      'neko'
    ]
  }
}
```

公式にi18nでの例があります。参考にしてください。
https://ja.nuxtjs.org/examples/i18n/

# バリデーションしたい
先ほどちょっと出てきたVeeValidateが便利です。
pluginの設定については先ほどの通りです。ファイルを作ったらnuxt.config.jsに登録してください。

```Vue:/nuxt/pages/hogehoge.vue
<template>
  <form>
    <input
      v-validate="{required: true}"
      v-model="catName"
      data-vv-as="猫の名前"
      data-vv-validate-on="blur"
      name="catName"
      type="text" />
    <p v-show="errors.has('catName')">{{ errors.first('catName') }}</p>
  </form>
</template>
```

これで一度アクティブにしたinputからフォーカスを外すと必須エラーが出ます。

また、これも先ほど少し出てきたように、pluginsのファイルに色々設定を追加できます。

# index.htmlを改変したい
次のファイルを作成します。

```html:/nuxt/app.html
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>
```

あとは任意のクラス名を付与したり、タグを追加すれば、その通りに反映されます。

## index.html内で他言語のMustache構文を使用したい
（まあそんなケース滅多にないでしょうが）

```html:/nuxt/app.html
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    <p>{{`\{\{$nekochan\}\}`}}</p>
    {{ APP }}
  </body>
</html>
```

index.htmlをindex.blade.phpに変換し、blade側で何らかの値を展開する場合を想定しています。

# SessionStrageについて
SPAでNuxtを使う場合、当然ながらF5を押せば保持していた値は消えてしまいます。
**いやだ！　消えてほしくない！！**
という場合は、SessionStrageを使いましょう。

```JavaScript
sessionStorage.setItem('nanikaNoFlg', true)
```

```JavaScript
const flg = sessionStorage.getItem('nanikaNoFlg')
```

データはsessionの終了まで保持されます。

## sessionが終了しても保持したい！
LocalStrageを使用しましょう。
ただしデータの期限が存在しないため、適切なタイミングでデータを削除する必要があります。

```JavaScript
localStorage.removeItem("nanikaNoFlg")
```

# おわりに
良きNuxt.jsライフを！

# おまけ
私も[癒し](https://qiita.com/shibakichiCafe/items/1d77dce63db3ff4e29f8)が欲しくなったので、癒しっぽいものを作りました。
https://codepen.io/nanaya910/pen/zawrqN