Vue.js / JSON から情報を引っ張ってくる その6
やること
- ポートフォリオページ のコンテンツのエンドポイントを WP REST API を用いて作成
- カテゴリー絞り込みを実装する
WordPress側(functions.php)でのAPIへのフィールド追加
display
という自前のデータを v-show:
を使って判定させるため下記をfunctions.phpに追加。
// ---------------------------------------- // `customData.display` のAPI登録 // ---------------------------------------- function register_my_custom_data() { register_rest_field( 'post', 'customData', array( 'get_callback' => 'get_my_custom_data', 'update_callback' => null, 'schema' => null, ) ); } add_action( 'rest_api_init', 'register_my_custom_data' ); function get_my_custom_data() { return array( 'display' => true ); }
これでJSON側には
"customData":{ "display":true }
のように出力される。
静的なクラスと動的なクラス
<a :class="['naviLink' , { 'is-selected': category.selected }]">...</a>
とすると、 .naviLink
というクラスは付きつつも、.is-selected
は selected
は true
の場合だけつくようになる。
App.vue
<template> <div id="app"> <header> <h1>works.yuheijotaki.com</h1> <nav> <ul> <li v-for="(category,index) in categories" :key="index"> <a href="javascript:void(0);" @click="filterCategory" :data-category="category.name" :class="['naviLink' , { 'is-selected': category.selected }]">{{category.name}}</a> </li> </ul> </nav> </header> <main> <ul> <li v-for="(post,index) in posts" :key="index" v-show="post.customData.display"> <a :href="post.acf.post_url" target="_blank"> <figure><img :src="post.images.full" :alt="post.title.rendered"></figure> <div class="wrap" :style="{ color: post.acf.post_color_letter, background: post.acf.post_color_bg }"> <div class="inner"> <h2>{{post.title.rendered}}</h2> <p>{{post.category_name}}</p> </div> </div> </a> </li> </ul> </main> </div> </template> <script> // normalize.css を読み込む import "normalize.css"; // Ajax通信ライブラリ import axios from "axios"; export default { name: "App", data() { return { categories: [ { name: 'All', selected: true }, { name: 'Front-end', selected: false }, { name: 'WordPress', selected: false }, { name: 'Web Design', selected: false }, { name: 'Tumblr', selected: false } ], posts: [] } }, created: function(){ this.request(); }, methods: { request: function(){ axios.get( 'https://works.yuheijotaki.com/wp-json/wp/v2/posts?per_page=100' ) .then( response => { this.posts = response.data; // console.log(this.posts); }) .catch( error => { console.log(error); }); }, filterCategory: function(event) { // カテゴリーがクリックされたとき用のメソッド // 全体のナビゲーションのクラス削除 var targetElements = document.getElementsByClassName('naviLink'); [].forEach.call(targetElements, function(elem) { elem.classList.remove('is-selected'); }); // 選択したナビゲーションのクラス付与 event.currentTarget.classList.add('is-selected'); // 投稿の取得 const posts = this.posts; const selectedCategory = event.currentTarget.getAttribute('data-category'); // クリックしたカテゴリーの取得 if ( selectedCategory !== 'All' ) { // `All` 以外を選択した場合 for (var i = 0; i < posts.length; i++) { // 投稿ごとのループ const categories = posts[i].category_name; // 投稿のカテゴリーを取得 const categoriesArray = categories.split(' ,'); // 取得したカテゴリーを配列に変換 for (var j = 0; j < categoriesArray.length; j++) { // 投稿内のカテゴリーごとのループ if ( categoriesArray.indexOf(selectedCategory) >= 0 ) { // 投稿に属するカテゴリーが含まれる場合 posts[i].customData.display = true; break; } else { // マッチしない場合 posts[i].customData.display = false; } } } } else { // `All` を選択した場合 for (var i = 0; i < posts.length; i++) { // 投稿ごとのループ posts[i].customData.display = true; // すべての投稿の `display` を `true` に } } } } }; </script>
まとめ
- 基本的な構文への慣れはだいぶできた気がする。理解して使いこなせているかというとまだまだですが。。
- やっぱりドキュメントは公式のが一番いいですね。ベースは公式を参考して発展的な使い方はググるのがいまのところ近道な気がします。
- カテゴリーのクラス付与/削除はいまクラスの
.add
と.remove
でやってしまってますが、本来はcategories.selected
の値をいじるほうがよさそう。 - URLが変更しないので変更できるようにしたい。
そのほか参考リンク