📮

【Vue3】郵便番号から住所自動入力を行う

2024/07/13に公開
4

はじめに

Vue3アプリケーションにおける郵便番号APIを利用した住所自動入力機能です。
APIサービスの選定から実装までを記載します!

完成イメージ

使用技術

  • Vue.js v3.3.7
  • axios v1.1.2
  • axios-jsonp v1.0.4

郵便番号APIサービスの選定

以下4サービスのAPI仕様を確認し、個人的に扱いやすい且つ住所データが更新し続けられている、
株式会社アイビスの郵便番号API」を採用しました。

https://zipcloud.ibsnet.co.jp/doc/api
https://zipaddress.net/
https://www.npmjs.com/package/yubinbango-core2
https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/zipcodesearch.html

POSTMANでレスポンスデータ確認してみよう

いざ、実装してみよう👍

1. データファイルを作成

事前に処理内で利用していくデータ格納ファイルを作っておきます。

都道府県データファイル
/src/config/pref.js
/**
 * 都道府県
 */
export default {
  display: [
    { id: 1, text: '北海道' },
    { id: 2, text: '青森県' },
    { id: 3, text: '岩手県' },
    { id: 4, text: '宮城県' },
    { id: 5, text: '秋田県' },
    { id: 6, text: '山形県' },
    { id: 7, text: '福島県' },
    { id: 8, text: '茨城県' },
    { id: 9, text: '栃木県' },
    { id: 10, text: '群馬県' },
    { id: 11, text: '埼玉県' },
    { id: 12, text: '千葉県' },
    { id: 13, text: '東京都' },
    { id: 14, text: '神奈川県' },
    { id: 15, text: '新潟県' },
    { id: 16, text: '富山県' },
    { id: 17, text: '石川県' },
    { id: 18, text: '福井県' },
    { id: 19, text: '山梨県' },
    { id: 20, text: '長野県' },
    { id: 21, text: '岐阜県' },
    { id: 22, text: '静岡県' },
    { id: 23, text: '愛知県' },
    { id: 24, text: '三重県' },
    { id: 25, text: '滋賀県' },
    { id: 26, text: '京都府' },
    { id: 27, text: '大阪府' },
    { id: 28, text: '兵庫県' },
    { id: 29, text: '奈良県' },
    { id: 30, text: '和歌山県' },
    { id: 31, text: '鳥取県' },
    { id: 32, text: '島根県' },
    { id: 33, text: '岡山県' },
    { id: 34, text: '広島県' },
    { id: 35, text: '山口県' },
    { id: 36, text: '徳島県' },
    { id: 37, text: '香川県' },
    { id: 38, text: '愛媛県' },
    { id: 39, text: '高知県' },
    { id: 40, text: '福岡県' },
    { id: 41, text: '佐賀県' },
    { id: 42, text: '長崎県' },
    { id: 43, text: '熊本県' },
    { id: 44, text: '大分県' },
    { id: 45, text: '宮崎県' },
    { id: 46, text: '鹿児島県' },
    { id: 47, text: '沖縄県' }
  ]
}
カタカナ変換用データファイル
/src/config/kanaMap.js
/**
 * カタカナ変換用データ
 */
export default {
  'ガ': 'ガ',
  'ギ': 'ギ',
  'グ': 'グ',
  'ゲ': 'ゲ',
  'ゴ': 'ゴ',
  'ザ': 'ザ',
  'ジ': 'ジ',
  'ズ': 'ズ',
  'ゼ': 'ゼ',
  'ゾ': 'ゾ',
  'ダ': 'ダ',
  'ヂ': 'ヂ',
  'ヅ': 'ヅ',
  'デ': 'デ',
  'ド': 'ド',
  'バ': 'バ',
  'ビ': 'ビ',
  'ブ': 'ブ',
  'ベ': 'ベ',
  'ボ': 'ボ',
  'パ': 'パ',
  'ピ': 'ピ',
  'プ': 'プ',
  'ペ': 'ペ',
  'ポ': 'ポ',
  'ヴ': 'ヴ',
  'ヷ': 'ヷ',
  'ヺ': 'ヺ',
  'ア': 'ア',
  'イ': 'イ',
  'ウ': 'ウ',
  'エ': 'エ',
  'オ': 'オ',
  'カ': 'カ',
  'キ': 'キ',
  'ク': 'ク',
  'ケ': 'ケ',
  'コ': 'コ',
  'サ': 'サ',
  'シ': 'シ',
  'ス': 'ス',
  'セ': 'セ',
  'ソ': 'ソ',
  'タ': 'タ',
  'チ': 'チ',
  'ツ': 'ツ',
  'テ': 'テ',
  'ト': 'ト',
  'ナ': 'ナ',
  'ニ': 'ニ',
  'ヌ': 'ヌ',
  'ネ': 'ネ',
  'ノ': 'ノ',
  'ハ': 'ハ',
  'ヒ': 'ヒ',
  'フ': 'フ',
  'ヘ': 'ヘ',
  'ホ': 'ホ',
  'マ': 'マ',
  'ミ': 'ミ',
  'ム': 'ム',
  'メ': 'メ',
  'モ': 'モ',
  'ヤ': 'ヤ',
  'ユ': 'ユ',
  'ヨ': 'ヨ',
  'ラ': 'ラ',
  'リ': 'リ',
  'ル': 'ル',
  'レ': 'レ',
  'ロ': 'ロ',
  'ワ': 'ワ',
  'ヲ': 'ヲ',
  'ン': 'ン',
  'ァ': 'ァ',
  'ィ': 'ィ',
  'ゥ': 'ゥ',
  'ェ': 'ェ',
  'ォ': 'ォ',
  'ッ': 'ッ',
  'ャ': 'ャ',
  'ュ': 'ュ',
  'ョ': 'ョ',
  '。': '。',
  '、': '、',
  'ー': 'ー',
  '「': '「',
  '」': '」',
  '・': '・'
}

2. vueコンポーネントを作成

フォーム要素・API処理を記載するVueコンポーネント(FormAddress.vue)を作成します。

FormAddress.vue
<script setup>
import { ref } from 'vue'
import configPref from '@/config/pref.js'
import axios from 'axios'
import jsonpAdapter from 'axios-jsonp'

const zipCode = ref('')
const prefecture = ref('')
const address = ref('')
const furiganaAddress = ref('')

/**
 * 郵便番号から住所を自動設定
 */
const fetchAddress = async (inputZipCode) => {
  // 郵便番号は7桁の場合にAPIリクエスト実行
  if (inputZipCode.length === 7) {
    await axios.get(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${inputZipCode}`, {
      adapter: jsonpAdapter
    })
      .then((response) => {
        if (response.data.results) {
          // レスポンスデータをリアクティブデータに反映する
          const { prefcode, address2, address3, kana2, kana3 } = response.data.results[0]
          prefecture.value = prefcode
          address.value = address2 + address3
          furiganaAddress.value = kana2 + kana3
        }
      })
  }
}
</script>

<template>
  <div class="form-group">
    <p>郵便番号</p>
    <input
      v-model="zipCode"
      @input="fetchAddress(zipCode)"
      type="text"
      id="zipCode"
      name="zipCode"
    >
  </div>
  <div class="form-group">
    <p>都道府県</p>
    <select
      v-model="prefecture"
      id="prefecture"
      name="prefecture"
    >
      <option disabled value="">都道府県</option>
      <option
        v-for="pref in configPref.display"
        :key="pref.id"
        :value="pref.id"
      >{{ pref.text }}</option>
    </select>
  </div>
  <div class="form-group">
    <p>市区町村・番地</p>
    <input
      v-model="address"
      type="text"
      id="address"
      name="address"
    >
  </div>
  <div class="form-group">
    <p>市区町村・番地(ふりがな)</p>
    <input
      v-model="furiganaAddress"
      type="text"
      id="furiganaAddress"
      name="furiganaAddress"
    >
  </div>
</template>

一旦検証してみよう

ここまで行うと基本的な機能実装は終え、👇のような形となるかと思います。(cssとかはご自身であててね)
しかし、よく見ると「市区町村・番地(ふりがな)」が半角カタカナになっていますね!
では次は「半角カタカナ」を「全角ひらがな」に変換する処理を作っていきましょう🙏

3. 「半角カタカナ」 → 「全角ひらがな」に変換する

変換の流れは以下の流れで作っていきます。
「半角カタカナ」→「全角カタカナ」→「全角ひらがな」に変換

3-1. 「半角カタカナ」を「全角ひらがな」に変換する処理を作る

別途、変換処理を明記するconvert.jsを作成していきましょう!

/src/utilities/convert.js
import kanaMap from '@/config/kanaMap.js'

/**
 * 半角カタカナを全角カタカナに変換
 * @param str
 * @returns {string}
 */
const kanaRegex = new RegExp('(' + Object.keys(kanaMap).join('|') + ')', 'g')
export const hankakuToZenkaku = str => {
  return str.replace(kanaRegex, match => kanaMap[match])
    .replace(//g, '゙')
    .replace(//g, '゚')
}

/**
 * 全角カタカナをひらがなに変換
 * @param str
 * @returns {string}
 */
export const kanaToHiragana = str => {
  return str.replace(/[\u30a1-\u30f6]/g, s => String.fromCharCode(s.charCodeAt(0) - 0x60))
}

3-2. 住所自動入力処理を更新する(ひらがなで表示されるようにする)

先ほど作成したFormAddress.vueに追記をしていきます。

FormAddress.vue
<script setup>
import { ref } from 'vue'
import configPref from '@/config/pref.js'
// ↓ 追加
import { hankakuToZenkaku, kanaToHiragana } from '@/utilities/convert.js'
import axios from 'axios'
import jsonpAdapter from 'axios-jsonp'

const zipCode = ref('')
const prefecture = ref('')
const address = ref('')
const furiganaAddress = ref('')

/**
 * 郵便番号から住所を自動設定
 */
const fetchAddress = async (inputZipCode) => {
  if (inputZipCode.length === 7) {
    await axios.get(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${inputZipCode}`, {
      adapter: jsonpAdapter
    })
      .then((response) => {
        if (response.data.results) {
          const { prefcode, address2, address3, kana2, kana3 } = response.data.results[0]
          // ↓ 追加
          const kanaAddress = kanaToHiragana(hankakuToZenkaku(kana2 + kana3))
          prefecture.value = prefcode
          address.value = address2 + address3
          // ↓ 変更
          // furiganaAddress.value = kana2 + kana3
          furiganaAddress.value = kanaAddress
        }
      })
  }
}
</script>

...以下省略

再度、検証してみよう

無事に郵便番号から住所情報を取得でき、ひらがな変換もできているかなと思います👍

まとめ

今回はVue3アプリケーションにおける郵便番号APIを利用した住所自動入力機能をご紹介しました!
記事の中では基本的な処理のみをご紹介しましたが、👇では少しだけUI整えているので興味あれば覗いてみてください👀
以上、あざした!!!!
https://github.com/Foooriii/vue-postCodeAPI-demo

Discussion