前置き
- 私はこうしています、という内容です。
- こうすべきと言う話ではないので、ご意見・ご感想をいただければ幸いです。
現状の課題
- v-ifに具体的な条件式が書かれている状態
- 特定のデータを参照するためにアクセスする方法が複雑
- APIを改修せずにフロントエンドのロジックでどうにかする必要がある
// 具体的な条件式が書かれている
<div v-if="offer.stage === 40"></div>
// 複雑な構造のオブジェクト
<div>{{ deta[0].delivery.arrivalAddressData }}</div>
基本方針
- ロジックを純粋なJS(TS)ファイルに定義する。
- .vueファイル内で上記定義したロジックをインポートして使う
ロジックの定義方針
巨大なcommon.jsを作らない(重要)
1ファイルにいろんなロジックを詰め込みすぎないために…
- 概念(ドメイン)ごとにファイルを分割して定義する
- 例:ユーザー名、データの状態、など
- DBのカラム名単位
- DBのテーブル単位(1つのテーブル全体である情報を表している場合)
plugin配下にフォルダを作ってまとめる
フォルダ構成
/plugins
/serviceUtils
/offer
- offerType.js
- price.js
...
/entry
- entryInfo.js
...
定義方法
- 必要な関数・定数を定義
- メソッド単位でもまとめてでのインポートもできるように、名前付きエクスポート、デフォルトエクスポートを設定する
- 基本的に構成は同じだが、名前付きエクスポートの方は定数をエクスポートする場合、別途名前空間を切っても良いかも。
sample.js
const isNuxt = value => value === 'Nuxt'
const isVue = value => value === 'Vue'
export {
isNuxt,
isVue
}
export default {
isNuxt,
isVue
}
使い方
インポート
page, component, layout配下のそれぞれの.vueファイル内でimportして使う
// メソッド単位
import { isNuxt } from '~/plugins/serviceUtils/sample'
// まとめて
import sample from '~/plugins/serviceUtils/sample'
methodsで使う
必要に応じて使い分ける
- methodsに定義する
- データを渡した状態で実行する
- 独自ロジックの一部として使用する
methods: {
// そのまま使う場合は
isNuxt,
isVue() {
// 同じ名前で使用するが、ページ内の何らかのデータを渡した状態で実行したい場合
return isVue(this.data)
},
// ロジックの一部として使用する場合
myFunc() {
const isOk = isVue()
...
}
}
<!-- v-for内の分岐などで、HTML上で引数を渡したい・渡すしかない場合 -->
<div v-if="isVue(data)">Vue</div>
<!-- HTML上で引数を渡す必要がない場合 -->
<div v-if="isVue()">Vue</div>
<div v-else-if="isNuxt()">Nuxt</div>
computedで使う
状態判定をしたい場合など。
computed: {
isNuxt() {
return isNuxt(this.data) // dataが書き換わるたびに判定が切り替わる
}
}
メソッドで定義した場合と違い、使う時にカッコを使わなくなる
<div v-if="isNuxt">Nuxt</div>
メリット
- thisを使う必要がなくなる
- ロジックを集約できる
- TS化しやすい
- やろうと思ったらできるなぐらいの認識だったが、試しにTS化してみたら簡単にできた。
- ファイル全体をTS化する必要があるが、行数が少ない状態で別れているので、段階的に移行しやすい。
- ピュアなJSなので、TypeScript公式の知識だけで移行できる(Nuxt,Vue独自の概念を使う必要ない)
- そのファイルでのみ使えるプライベートメソッドを定義して使える(後述)
- 影響範囲が限られているのでリファクタリングしやすい
- 公開するメソッドと非公開のメソッドを制御できる
プライベートメソッドの使用例
// private
const find = (data, str) => data.find(v => v.key === str)
const findNuxt = data => find(data, 'nuxt')
const findNuxt = data => find(data, 'vue')
// public
const getName = (data) => {
const nuxt = findNuxt(data)
const vue = findVue(data)
return nuxt || vue || ''
}
// 外部に公開しているのはgetNameのみ
export {
getName
}
export default {
getName
}
比較
普通に定義
methods: {
isNuxt(data) {
return data === 'nuxt'
},
...
}
インポートする場合
その1
import { isNuxt } from '~/plugins/serviceUtils/sample'
methods: {
isNuxt,
...
}
その2
import { isNuxt } from '~/plugins/serviceUtils/sample'
methods: {
isNuxt(data) {
return isNuxt(data)
}
...
}