📗
Nuxt.js+Vuetify+axiosで外部APIから取得した情報を表示するまで
Nuxt.jsのプロジェクトでaxiosを使ってAPIから情報を取ってきた情報をVuetifyで表示する。
完成イメージ
Zenn Trend APIで取得した情報を一覧として表示する。
プロジェクト作成
- create-nuxt-appを使ってプロジェクト作成をする。
- composition-apiとdate-fnsをインストールする。
npm install -g yarn
yarn add nuxt
yarn create nuxt-app nuxt_vuetify_sample
cd nuxt_vuetify_sample
yarn add --dev @nuxtjs/composition-api
yarn add --dev @nuxtjs/date-fns
参考
実装
見やすさ重視でソースは1つにしたが、実際の開発では色々切り分けた方が良いと思う。
zennTechTrendList.vue
<template>
<div>
<h1>Zennトレンド一覧(Tech)</h1>
<v-data-table
:headers="headers"
:items="state.articles"
:items-per-page="5"
class="elevation-1"
>
<template #[`item.publishedAt`]="{ item }">
{{ $dateFns.format(item.publishedAt, 'yyyy-MM-dd HH:mm:ss') }}
</template>
</v-data-table>
</div>
</template>
<script lang="ts">
import {
defineComponent,
reactive,
useContext,
onMounted,
} from '@nuxtjs/composition-api'
type Article = {
title: string
likedCount: number
publishedAt: string
}
type State = {
articles: Article[]
}
export default defineComponent({
setup() {
const headers = [
{ text: '記事名', value: 'title' },
{ text: 'いいね数', value: 'likedCount' },
{ text: '公開日時', value: 'publishedAt' },
]
const state = reactive<State>({
articles: [],
})
const { $axios } = useContext()
const getZennArticles = async () => {
const url = 'https://zenn-api.netlify.app/.netlify/functions/trendTech'
const response = await $axios.$get<Article[]>(url)
state.articles = response
}
onMounted(() => {
getZennArticles()
})
return { headers, state }
},
})
</script>
import・定義
Composition APIで使用するもののみインポートする。表示する記事情報にArticleとして定義する。また、Articleは複数取得するので、Stateで配列として扱う。
import {
defineComponent,
reactive,
useContext,
onMounted,
} from '@nuxtjs/composition-api'
type Article = {
title: string
likedCount: number
publishedAt: string
}
type State = {
articles: Article[]
}
defineComponent
Vue コンポーネントオブション中でTypeScriptに型を推論してもらうためにdefineComponent内で色々書く。
- headers:テーブルのヘッダー
- state:外部APIから取得した記事情報。
- $axios:外部APIと通信するもの。
- getZennArticles:外部APIと通信してstateに記事の情報を入れる関数。
headersとsteteをreturnするとtemplate内で使用できるようになる。
export default defineComponent({
setup() {
const headers = [
{ text: '記事名', value: 'title' },
{ text: 'いいね数', value: 'likedCount' },
{ text: '公開日時', value: 'publishedAt' },
]
const state = reactive<State>({
articles: [],
})
const { $axios } = useContext()
const getZennArticles = async () => {
const url = 'https://zenn-api.netlify.app/.netlify/functions/trendTech'
const response = await $axios.$get<Article[]>(url)
state.articles = response
return response
}
onMounted(() => {
getZennArticles()
})
return { headers, state }
},
})
参考
Vuetify
Vuetifyを使用して、記事一覧を作成する。
今回は「v-data-table」を使用する。
v-data-table
- headers:defineComponentで設定したheadersが適用される。
- items:defineComponentで設定したstateのうちarticlesが適用される。
- items-per-page:1ページあたりの記事の表示数。デフォルトは10。
- elevation-1:コンポーネントの高さを設定。数値によってテーブルが浮く。
v-data-tableはitem.<name> を使用すると、特定の列のみをカスタマイズできるので、publishedAtは「yyyy-MM-dd HH:mm:ss」に変換する。変換処理にはdate-fnsを使用する。
<template>
<div>
<h1>Zennトレンド一覧(Tech)</h1>
<v-data-table
:headers="headers"
:items="state.articles"
:items-per-page="5"
class="elevation-1"
>
<template #[`item.publishedAt`]="{ item }">
{{ $dateFns.format(item.publishedAt, 'yyyy-MM-dd HH:mm:ss') }}
</template>
</v-data-table>
</div>
</template>
参考
Discussion