"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

Select選択値の変数へのバインドと、@changeイベントハンドリング/NUXT自己流チュートリアル(1)-4

今回は、Selectの選択値の変数へのバインドです。

あわせて2つのSelectを並べて、片方の選択内容にあわせて、もうひとつのSelectの内容を更新するのをやってみます。

f:id:arakan_no_boku:20190509225706p:plain

この記事は「NUXT自己流チュートリアル(1)」として続き物で書いている記事の4回目です。

1回目から続けて読んでもらえることを想定して書いていますのでご了承ください。

arakan-pgm-ai.hatenablog.com

 

今回のテーマについて 

 

NUXT自己流チュートリアル(3)では、onClickイベントを例にしましたが、もうひとつ重要な「onChange」イベントを扱います。

v-onと省略形の「@」のどちらでも使えるので。

  • v-on:change
  • @change

のいずれかを利用することになります。

選択には、<Select>タグを使います。

UIフレームワーク「Buefy」には拡張された<b-select>というのもあるのですが、<b-select>だと、@changeでうまくイベントが拾えません。 

今回は、@changeでイベントトリガを使うので、<Select>を使います。

<b-select>を使う場合は、@changeではなく@inputを使います。

そのパターンはこちらの記事です。

arakan-pgm-ai.hatenablog.com

 

今回の記事の前提的なこと

 

自己流チュートリアル(1)で「前提」と「チュートリアルの準備」として書いていることは、できている必要があります。

つまり。

インストール・環境設定・テスト専用Chromeショートカットの作成うんぬんですね。

まだの方は、下記記事を先に参照して、環境設定をお願いします。

arakan-pgm-ai.hatenablog.com

 

あと、都道府県・市町村データ取得のWEB-APIを使います。

API-KEYが必要になるので、まだ取得していない場合は、以下で登録してAPI-KEYを取得しておいてください。

f:id:arakan_no_boku:20190902202557p:plain

https://opendata.resas-portal.go.jp/

 

今回の目的

 

NUXT自己流チュートリアル(2)で都道府県コード固定でWEB-APIからデータの取得と<table>を使った表示をやりました。 

ソースは「cityapi.vue」です。

今回は、そこを変更して、都道府県情報・市町村情報共、Selectにします。 

新たに必要になる技術要素は。

  • Selectで選択されているコードを変数におさめる(選択バインディング
  • Selectにイベントトリガ(@change)をつけて、市町村取得メソッドを実行させる。

みたいなことです。 

 

ソースコードです

 

全体的には、NUXT自己流チュートリアル(2)をベースにします。

その中の「cityapi.vue」だけを変更していくことになります。

処理概要を簡単に書くと。

NUXT自己流チュートリアル(2)では都道府県コード固定でしたが、今回は。

  1. 初期処理で都道府県のリストを取得して、上段の「Select」にセットする。
  2. 上段の「Select」で都道府県が選択された(onChange)のをひろう。
  3. 上記をトリガにして、市区町村情報を取得しなおす。
  4. 取得した市区町村情報を、下段の「Select」を更新する。

ということをやります。

修正後のソース全体がこちらです。

pages/cityapi.vue 

<template>
  <div>
    <NLink to="/">
      ルートのページへ戻ります
    </NLink>
    <br>
    <img src="/jamap.JPG" alt="image03">
    <div v-if=" prefecturesJson.message == null">
      <select v-model="prefecturesSelected" @change="updateMunicipalitiesJson({prefecturesSelected})">
        <option value="" />
        <option v-for="pOption in prefecturesJson.result" :key="pOption.id" :value="pOption.prefCode">
          {{ pOption.prefName }}
        </option>
      </select>
    </div>
    <div v-if="municipalitiesJson != null">
      <div v-if="municipalitiesJson.message == null">
        <select v-model="municipalitiesSelected">
          <option v-for="mOption in municipalitiesJson.result" :key="mOption.id" :value="mOption.cityCode">
            {{ mOption.cityName }}
          </option>
        </select>
      </div>
    </div>
    <div v-else>
      <select v-model="municipalitiesSelected">
        <option value="" />
      </select>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
export default {
  data () {
    return {
      prefecturesSelected: '',
      municipalitiesSelected: '',
      municipalitiesJson: null
    }
  },
  asyncData () {
    return axios
      .get('https://opendata.resas-portal.go.jp/api/v1/prefectures', {
        headers: {
          'X-API-KEY': 'noxxxxxxxxxxxxxxxxxxxxxxxxxOjK'
        },
        data: {}
      })
      .then((res) => {
        return { prefecturesJson: res.data }
      })
  },
  methods: {
    async updateMunicipalitiesJson ({ prefecturesSelected }) {
      const url = `https://opendata.resas-portal.go.jp/api/v1/cities?prefCode=${prefecturesSelected} `
      await axios
        .get(url, {
          headers: {
            'X-API-KEY': 'noxxxxxxxxxxxxxxxxxxxxxxxxOjK'
          },
          data: {}
        })
        .then((res) => {
          this.municipalitiesJson = res.data
        })
      return this.municipalitiesJson
    }
  },
  head: {
    title: 'CityApi page'
  }
}
</script>

ポイントを確認していきます。

 

変数の定義と初期化

 

まず、変数の定義と初期化です。

data()の中で

prefecturesSelected:'',
municipalitiesSelected:'',
municipalitiesJson:null

 を定義・初期化しています。

これを忘れると変数が未定義だと怒られます。

都道府県データをおさめる「prefecturesJson」は、asincData()の中で取得して初期セットしているので、こちらには書きません。

 

Selectへの情報セットと変数へのバインド

 

Selectの中で選択されたコードを収める変数は、「v-model」でひもつけます。

<select v-model="municipalitiesSelected">

 や

<select v-model="municipalitiesSelected">

な感じです。

そこで収められるのは<option>タグのvalueの値です。

APIで取得した「prefecturesJson」や「municipalitiesJson」に収めたデータは、「v-for」のループでおさめていきます。

市町村データ「municipalitiesJson」の場合でいくと。

<option v-for="mOption in municipalitiesJson.result" v-bind:key="mOption.id" v-bind:value="mOption.cityCode">

という感じになります。

v-for="mOption in municipalitiesJson.result" v-bind:key="mOption.id"

までは、NUXT自己流チュートリアル(2)で説明したのと同じですが

今回の場合は後ろに以下がついてます。

v-bind:value="mOption.cityCode"

つまり、optionのvalueに、json内のcityCodeをセットしています。

 

@changeでonChangeイベントを拾う

 

もうひとつのポイントはこちらです。

<select v-model="prefecturesSelected" @change="update_municipalitiesJson({prefecturesSelected})">

都道府県のSelectに「@change」で「updateMunicipalitiesJson({prefecturesSelected})」メソッドを紐付けます。

このメソッドは「 methods:」の中で定義していて、選択された都道府県コードをキーに、中で市町村情報を取得するAPIを使ってデータを取得し、「this.municipalitiesJson = res.data」で、市町村情報のSELECTの内容を書き換えているわけです。

 

さて実行してみます

 

プロジェクトをカレントフォルダにして「npm run dev」して、「http://localhost:3000」で表示します。

もちろん、Originチェックを回避できる「テスト用ショートカット」から起動したものですよ。

さて。

f:id:arakan_no_boku:20190516234656p:plain

ここから「市区町村のサンプル」のリンクをクリックします。

f:id:arakan_no_boku:20190516234814p:plain

都道府県のSELECTを開いたところです。

ここで、東京でも選んでみます。

f:id:arakan_no_boku:20190516234944p:plain

スパっと、東京都の市区町村が表示されます。

いい感じですねえ。

今回は、こんなところで。

ではでは。