27
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nuxt.jsのasyncData メソッドを使ってRSSを読み込む

Posted at

この記事はオールアバウトアドベントカレンダー18日目の記事です

Nuxt.jsの機能を使って
RSSを取得して値を書き出してみます

使う機能

asyncData メソッド

サーバーサイドでデータを取得し、それをレンダリングしたいことがあるでしょう。Nuxt.js はコンポーネントのデータをセットする前に非同期の処理を行えるようにするために asyncData メソッドを追加しています。

参照: https://ja.nuxtjs.org/guide/async-data/

手順

前準備

  • npm install xml2js
    • XMLを扱うのでparseしてくれるモジュールinstallしておく

コンポーネントを用意する

pages/rss.vueという名前のpageコンポーネントを用意します
先に完成形を↓↓

pages/rss.vue
<template>
  <div>
    <ul>
      <li v-for="item in data">
        <a v-bind:href="item.link">
          {{item.title}}
        </a>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    asyncData ({params}, callback) {
      axios.get(`RSSのURL`)
        .then((res) => {
          var parseString = require('xml2js').parseString
          var xml = res.data
          parseString(xml, (message, xmlres) => {
            callback(null, {data: xmlres.rss.channel[0].item})
          })
        })
        .catch((e) => {
          callback({ statusCode: 404, message: 'ページが見つかりません' })
        })
    }
  }
</script>

<style>
</style>

部分的に説明していきます

まず、asyncData() {}を用意します

非同期処理を行ってくれます

pages/rss.vue
<script>
  export default {
    asyncData ({params}, callback) { // ←非同期処理をしてくれる関数
    }
  }
</script>

XMLを取得していきます

今回はaxiosを使っています
取得した結果はres.dataのオブジェクトに格納されます

pages/rss.vue
<script>
  export default {
    asyncData ({params}, callback) {
      axios.get(`RSSのURL`)
        .then((res) => {
          console.log(res.data) // xmlが入ってる
        })
        .catch((e) => {
        })
    }
  }
</script>

XMLをparseします

pages/rss.vue
          var parseString = require('xml2js').parseString
          var xml = res.data // XML入ってる
          parseString(xml, (err, xmlRes) => {
        console.log(xmlRes) // xmlResはXMLをオブジェクトに変換した形
          })

前準備でいれたxml2jsを使って取得したXMLをparseします

書き出しの時に扱えるようにdataに登録する

pages/rss.vue
          parseString(xml, (err, xmlRes) => {
        callback(null, {data: xmlres.rss.channel[0].item})
          })

callback(null, {<変数名>: <データ>}) とすることで
変数に登録できます
今回の場合、<template>のところで使います

XMLが無かったときの処理

pages/rss.vue
        .catch((e) => {
          callback({ statusCode: 404, message: 'ページが見つかりません' })
        })

XMLが取得できなかったときの事を考え
取得できなかったら,404を返すようにします

ビューに書き出す

あとはお好みでいい感じに書き出してください

pages/rss.vue
<template>
  <div>
    <ul>
      <li v-for="item in data">
        <a v-bind:href="item.link">
          {{item.title}}
        </a>
      </li>
    </ul>
  </div>
</template>

実際にやった結果

適当なRSSを読み込み元として
http://localhost:3000/rss/ にアクセスした結果がこちら

スクリーンショット 2017-12-19 14.22.20.png

無事取得できてますねー
こんなかんじでズラ~と出てきます

[おまけ]URLに応じて読み込むRSSを変えたい時

pases/category/_name.vueを作った時
Nuxt.jsは http://localhost:3000/category/<なんか>/
というルーティングを作ってくれます
参照: https://ja.nuxtjs.org/guide/routing#動的なルーティング

その<なんか>の部分を使ってRSSの読み込み先を変更することも可能です

サンプル↓↓

pases/category/_name.vue
<script>
  import axios from 'axios'

  export default {
    asyncData ({params}, callback) {
      axios.get(`https://rss.allabout.co.jp/aa/latest/ch/${params.name}`)
        .then((res) => {
          var parseString = require('xml2js').parseString
          var xml = res.data
          parseString(xml, (message, xmlres) => {
            callback(null, {data: xmlres.rss.channel[0].item})
          })
        })
        .catch((e) => {
          var result = { statusCode: 404, message: 'ページが見つかりません' }
          callback(result)
        })
    }
  }
</script>

${params.name}でURL上の引数を取得することが出来ます、便利!

まとめ

ブラウザへのレンダリング前に実行してくれるasyncDataは
非同期処理のことを考える手間を減らしてくれて最高です

Vue.jsには無かったメソッドな気がする(別でnpm installすればある)ので
コレだけでもNuxt.jsを使いたくなりますね

27
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?