OpenWeatherMap APIで天気情報を取得する(Vue.js)

Vue.js

OpenWeatherMapのapiで過去、現在、未来予測の天気の情報を取得することができます。
無料から使い始めることができる点でも使いやすいです。
Vue.jsでOpenWeatherMapで天気情報を取得する方法を紹介します。

Vue.jsでOpenWeatherMap APIを使う方法

OpenWeatherMap APIを使うには、登録が必要です。
登録すると、API Keyが発行されます。

OpenWeatherMap APIを使うといろんなことができます。
現在の天気をジオロケーションを使って現在地から取得する方法と、都市名から取得する方法を紹介します。

現在の天気を取得する場合は、「Current Weather Data」を探します。
https://openweathermap.org/current

URL構成

urlの構成をみていきます。
基本的には、
http;//のあと、api.openweathermap.org/data/2.5/weather?が続き、その後にパラメーターが続きます。
都市名から検索して天気情報を取得したい場合は、次のようにパラメーターが続きます。
q={city name},{state code}&appid={API key}
q=London&appid={API key}

ジオロケーションから取得する場合は緯度と経度を指定します。
lat={lat}&lon={lon}&appid={API key}
lat=35&lon=139&appid={API key}

これを変数に変えて、利用します。

axiosの設定

いろいろやり方がありますが、axios.jsを作成して、Vueのプロトタイプに$axiosに格納します。
axios.js

<script>
import Vue from 'vue'
import axios from 'axios'

Vue.prototype.$axios = axios</script>

そうすることで、this.$axiosというかたちでアクセスできます。

まずは変数の初期値を設定

data()を使って、初期値を設定します。

  data() {
    return {
      search: '',
      weatherData: null,
      lat: null,
      lon: null,
      apiUrl: 'http://api.openweathermap.org/data/2.5/weather',
      apiKey:'OpenWeatherMapで取得したAPI Key'
    }
  },

url構成で確認したhttp ~ weatherまでの部分も変数として用意しておくとスッキリします。
緯度と経度をnullで初期化しておきます。
weatherDataは取得した天気の情報を格納する変数です。
searchは検索したときの入力を取得して格納するための変数です。

ジオロケーションを取得

現在地から天気情報を取得できるようにするために、まずは、ジオロケーションを取得します。

    getLocation() {
      navigator.geolocation.getCurrentPosition(position => {
        console.log('position: ', position);
        this.lat = position.coords.latitude
        this.lon = position.coords.longitude
        this.getWeatherByCoords()
      })
      },

methodsの中に、getLocation()メソッドを作成します。
getCurrentPositionで現在地を取得して、緯度と経度を格納します。
そして、ジオロケーションから天気情報を取得するためのgetWeatherByCoords()を実行します。

ジオロケーションから天気情報を取得する

templateには、クリックするとgetLocation()が発火して現在地を取得できるように、ボタンを作成します。

<button @click="getLocation">現在地を取得する</button>

そして、メソッドを作成します。

    getWeatherByCoords() {
      this.$axios.get(`
      ${this.apiUrl}?lat=${this.lat}&lon=${this.lon}
      &appid=${this.apiKey}&units=metric&lang=ja`)
    .then(response => {
        this.weatherData = response.data
      })
      },

methodsの中に、getWeatherByCoords()メソッドを作成します。
上で取得したジオロケーションの緯度と経度を使って、返されたPromiseのresponseを変数weatherDataに格納します。
そうすることで、いろんな情報を表示できるようになります。

天気情報の表示

<!-- 温度表示 -->
      <div>
        <div>{{weatherData.name}}</div>
        <div>{{weatherData.weather[0].main}}</div>
        <div>
      <span>{{ Math.round(weatherData.main.temp) }}</span>
          <span>&deg;C</span>
        </div>
      </div>

取得したデータの中身を確認してどんな情報がどこに格納されているのかを確認します。
そして、必要な情報を表示します。
温度は.main.tempに格納されていますが、小数点第二位まで表示されるので、Math.round()などで表示を整えます。
また、°Cなどはcssで調整が必要です。
天気のアイコンは、weatherのインデックス番号[0]番目にiconが格納されているのでその情報を取得します。
srcはv-bindすることで、動的に表示を切り替えることができます。

都市名から検索して天気情報を取得

      <input
        v-model="search"
        @keyup.enter="getWeatherBySearch"
        placeholder="検索..."
        >

とinputタグを作成します。
エンターキーで送信できるように、keyupにenterを設定して、getWeatherBySearch()というメソッドが発火するようにしています。

    getWeatherBySearch() {
      this.$axios.get(`
        ${this.apiUrl}?q=${this.search}
         &appid=${this.apiKey}&units=metric&lang=ja`)
     .then(response => {

        this.weatherData = response.data

      })
    }

methodsの中に、getWeatherBySearch()メソッドを作成します。
現在地から取得する場合とほとんど同じでurlの構成が少し異なる部分を修正します。

時間帯でアイコンを切り替える

https://openweathermap.org/weather-conditions
のIcon listを確認すると日中のアイコンはd(day)で終わり、夜の時間はn(night)で終わるpngファイルが使われていることがわかります。

    <div  :class="bgClass">
   <!-- 天気アイコン -->
      <div>
        <img :src="`http://openweathermap.org/img/wn/
     ${weatherData.weather[0].icon}@2x.png`"> 
      </div>
    </div>

天気アイコンを設定します。
v-bindでlassがついたら夜、つかなかったら昼のアイコンに切り替わるようにします。
この場合、computedを使います。
最後の文字を取得してtrue/falseを判断したい場合は、endsEith()を使います。

  computed: {
    bgClass() {
      if (this.weatherData) {
        // Day icon	はn、Night iconはnが最後
        if (this.weatherData.weather[0].icon.endsWith('n')) {
          return 'bg-night'
        } else {
          return 'bg-day'
        }
      }
    }
  },

endsWithといった文字列の操作は、JavaScriptで文字列を操作するを参考にしてみてください。

Vue.js

Posted by devsakaso