nuxt.jsでRESAS-APIの市区町村一覧を取得してVuexに格納する

RESAS-API概要

地域経済分析システムRESASが提供しているは市区町村一覧をAPIから取得する。

取得結果のサンプルは次のとおり。全コードはこちら。

  • prefCode:市区町村コード
  • prefName:市区町村名
  • bigCityFlag:特別区・行政区フラグ(0:一般の市区町村、1:政令指定都市の区、2:政令指定都市の市、3:東京都23区)
1
2
3
4
5
{ "message": null, 
"result": [
{ "prefCode": 1, "cityCode": "01100", "cityName": "札幌市", "bigCityFlag": "2" },
{ "prefCode": 1, "cityCode": "01101", "cityName": "札幌市中央区", "bigCityFlag": "1" }
] }

RESASを利用する準備

axiosをプラグイン化して、RESAS-APIを利用できる環境を整える。
詳細はこちらの記事を参照。

市区町村一覧をVuexに格納

ストアはモジュールモードを利用する。
storeディレクトリ内にcityList.jsを作成。

cityList.jslink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { cloneDeep } from 'lodash'

const initialState = {
cityList: [],
}

// ShallowCopyを避けるため、lodashのcloneDeepを用いる。
export const state = () => cloneDeep(initialState)

export const getters = {
getCityList: (state) => (prefCode) => {
return state.cityList.filter((f) => f.prefCode === prefCode)
},
}

export const mutations = {
initCitySet(state, payload) {
if (payload === null) {
state = cloneDeep(initialState)
} else {
state.cityList = payload
}
},
}

export const actions = {
async fetchCityAPI({ commit }) {
// APIから取得する場合
// const url = 'api/v1/cities'
// const { data } = await this.$resas.get(url)

// ローカルJSONから取得する場合
const data = await import('~/data/codes/citylist.json')
commit('initCitySet', data.result)
},
}

state

市区町村一覧を格納する変数cityListを設定。ShallowCopyを避けるため、lodashのcloneDeepを用いる。

1
2
3
4
const initialState = {
cityList: [],
}
export const state = () => cloneDeep(initialState)

actions

RESAS-APIから市区町村一覧を取得して、結果をmutationsに渡す。
ここでは、キー名resultのデータを抽出している。

1
2
3
4
5
6
7
export const actions = {
async fetchCityAPI({ commit }) {
const url = 'api/v1/cities'
const { data } = await this.$resas.get(url)
commit('initCitySet', data.result)
},
}

都道府県を指定したい場合は、パラメータにprefcodeを指定する。

1
2
3
4
5
6
7
8
export const actions = {
async fetchCityAPI({ commit }) {
const url = 'api/v1/cities'
const params = { prefCode: 28 }
const { data } = await this.$resas.get(url, { params })
commit('initCitySet', data.result)
},
}

都道府県一覧をJSONファイルに保存している場合は、ファイルをimportする。

1
2
3
4
5
6
export const actions = {
async fetchPrefAPI({ commit }) {
const data = await import('~/data/codes/citylist.json')
commit('initPrefSet', data.result)
},
}

mutations

取得した結果をstateに格納する。

1
2
3
4
5
6
7
8
9
export const mutations = {
initCitySet(state, payload) {
if (payload === null) {
state = cloneDeep(initialState)
} else {
state.cityList = payload
}
},
}

getters

stateの値は、gettersを介して参照する。
引数にprefCodeを指定して、該当する都道府県の市区町村データを抽出。

export const getters = {
getCityList: (state) => (prefCode) => {
return state.cityList.filter((f) => f.prefCode === prefCode)
},
}

middlewareの設定

SSRのクライアントサイドでレンダリングされる前にstoreに保存したいので、ミドルウェアを利用する。
middleware/vuex.jsを作成。

1
2
3
export default async ({ store }) => {
await store.dispatch('cityList/fetchCityAPI')
}

nuxt.config.jsでmiddlewareを有効化。

1
2
3
router: {
middleware: 'vuex' //ミドルウェアのファイル名
},

市区町村一覧を利用

コンポーネントでストアの値を取得するには、mapGettersを利用する。

1
2
3
4
5
6
7
8
9
10
11
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('cityList', ['getCityList']),
prefList() {
return this.getPrefList
},
},
}
</script>

例えばVuetifyのv-selectでセレクトボックスを作成するなら下記。
詳細なコードはここに置いている。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div>
<v-select
v-model="selectedPref"
:items="prefList"
item-text="prefName"
item-value="prefCode"
return-object
attach
chips
outlined
label="都道府県"
multiple
@change="$emit('input', $event)"
/>
</div>
</template>