WP REST APIとvue.jsとaxiosを使ってWordPressの記事を取得して一覧を表示する

WordPressの記事一覧を、WordPress外で表示する必要があったのでメモ。

## 環境
- WordPress 5.1.1
- vue.js 2.5.16
- axios 0.18.0

vue.jsとaxiosはCDNを使用。
WP REST APIは4.7移行から標準で使えるようになったらしい。

## ブラウザ
- Chrome（Win）
- FireFox（Win）
- Edge（Win）
- IE10/11（Win）
- Chrome（Android）
- Safari（iOS）

IEが後々足を引っ張ることに（　＾ω＾）・・・

## 作業開始

### 必要なファイルをindex.htmlに呼び出し
CDNでvueとaxiosを読み込み。
今回はindex.jsを作成してそこにvueの記述をするので、それも読み込み。

```html:index.html
<!-- 省略 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="/js/index.js"></script>
</body>
```

### index.jsにWordPerssから記事を取得するコードを作成

記事データを保存するdata.postsを作成。
インスタンス生成後にaxios使ってWordPressの記事取得して、取得したデータをdata.postsに格納。
catch書いとかないと記事が無かった時にコンソールエラーになるのでとりあえず記述。

```javascript:index.js
var app = new Vue({
  el: "#posts",
  data: {
    posts: []
  },
  created: function () {
    var _this = this;
    axios.get("http://[domain]/wp-json/wp/v2/posts/?_embed").then(function(response) { // [domain]にはドメインを指定
      response.data.forEach(function (elm) {
        var data = {
          title: elm.title.rendered,
          content: elm.excerpt.rendered,
          link: elm.link,
          category: elm._embedded["wp:term"],
          thumb: elm._embedded["wp:featuredmedia"]
        }
        _this.posts.push(data);
      });
    })
      .catch(function (error) {
        console.log("記事が取得できません。");
      })
  }
});
```

### 取得したデータで記事のリストを表示
v-show="posts.length !== 0"で記事が無い場合はコンテンツを非表示に。
後はv-forでdata.posts内の配列を回して、いい感じに記事一覧を作成。

```html:index.html
<div id="posts">
  <div v-show="posts.length !== 0" class="posts">
    <div class="posts-wrapper">
      <article class="post" v-for="post in posts" :key="post.id">
        <p class="post_img">
          <span v-if="post.thumb" :style="{'background-image': 'url(' + post.thumb[0].source_url + ')'}" class="thumb">
          </span>
          <span v-else class="post_img_none">
            no-image
          </span>
        </p>
        <div class="post_contents-area">
          <div v-if="post.category[0]" class="post_category-list">
            <span v-for="category in post.category[0]" :key="category.id" class="post_category">
              <a :href="category.link">{{ category.name }}</a>
            </span>
          </div>
          <a :href="post.link" class="post_link">
            <h3 class="post_title">{{ post.title }}</h3>
            <div class="post_content sp-none" v-html="post.content">
            </div>
          </a>
        </div>
      </article>
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="/js/index.js"></script>
</body>
```

これでいい感じに記事一覧ができましたー(＾０＾)♪

## ところがどっこい
IEで確認したところエラーががが…
そうですよね＾＾
Promise対応してないですよね＾＾
ありがとうございます！

IEの為にpolyfill追加して完成！

### [polyfill.io](https://cdn.polyfill.io/v3/)
> It's a service which accepts a request for a set of browser features and returns only the polyfills that are needed by the requesting browser.
これは、一連のブラウザ機能に対する要求を受け入れ、要求しているブラウザに必要なpolyfillのみを返すサービスです。

## 完成！！

```javascript:index.js
var app = new Vue({
  el: "#posts",
  data: {
    posts: []
  },
  created: function () {
    var _this = this;
    axios.get("http://[domain]/wp-json/wp/v2/posts/?_embed").then(function(response) { // [domain]にはドメインを指定
      response.data.forEach(function (elm) {
        var data = {
          title: elm.title.rendered,
          content: elm.excerpt.rendered,
          link: elm.link,
          category: elm._embedded["wp:term"],
          thumb: elm._embedded["wp:featuredmedia"]
        }
        _this.posts.push(data);
      });
    })
      .catch(function (error) {
        console.log("記事が取得できません。");
      })
  }
});
```
```html:index.html
<div id="posts">
  <div v-show="posts.length !== 0" class="posts">
    <div class="posts-wrapper">
      <article class="post" v-for="post in posts" :key="post.id">
        <p class="post_img">
          <span v-if="post.thumb" :style="{'background-image': 'url(' + post.thumb[0].source_url + ')'}" class="thumb">
          </span>
          <span v-else class="post_img_none">
            no-image
          </span>
        </p>
        <div class="post_contents-area">
          <div v-if="post.category[0]" class="post_category-list">
            <span v-for="category in post.category[0]" :key="category.id" class="post_category">
              <a :href="category.link">{{ category.name }}</a>
            </span>
          </div>
          <a :href="post.link" class="post_link">
            <h3 class="post_title">{{ post.title }}</h3>
            <div class="post_content sp-none" v-html="post.content">
            </div>
          </a>
        </div>
      </article>
    </div>
  </div>
</div>

<script src="https://cdn.polyfill.io/v3/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="/js/index.js"></script>
</body>
```