概要
フロント:Nuxt
バックエンド:Django REST Framework(以下DRF)
で新しいプロジェクトなどを立ち上げた時に設定などをいちいち調べるのがめんどくさくなったため、まとめておきます。
ただ、設定ファイルだけを書くのでは個人的に記事として物足りない。
なので、ついでに基本的な操作であるAPIを叩いてCRUDを行い、会員登録を実装するところまで書く予定です。
なお、今回はDBはSQLiteを使います。PostgreSQLやMySQLなど他のRDBが使いたい場合はDRF側のDBの設定を書きかえるだけなので、そちらの設定は各自よろしくお願いいたします。
この記事では、NuxtからDRFで作ったAPIを叩いてデータベースのから情報を取得、詳細な情報をクライアントサイドで表示させるところまでです。
ソースコードはこちらにあるのでわからないところは適宜見てください。
また、Twitterかこの記事のコメント欄でわからないところを聞いていただけると答えられます。
前回
Nuxt&Django REST FrameworkでCRUD GET編①
プロジェクト構成
前回はinspire.vue
に直接コードを追加して商品欄も一覧を追加しました。
しかしこれでは少し見た目的によろしくないので細かな変更を加えていきます。
Nuxtではpages内のvueファイルの木構造によってvue-routerに沿った設定が自動生成されます。
Nuxtドキュメントの例にもあるように、ディレクトリ構造が以下の場合には、
pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue
自動的に以下が生成されます
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}
こういった仕様のため、ルーティングに関しての手間が省けるという利点があります。
したがって、まず新しくpages
の中にitems
フォルダを新しく作り、その中にitemのidに応じて詳細ページを作れるように_id
フォルダを作ります。このようにフォルダの中に_id
フォルダを作ることで取得したidに応じた情報を自動的にページを精製してくれるようになります。
Githubを見ながらこの辺りを進めるとわかりやすいかと思います。
そして、items
フォルダにindex.vue
を作り、以下のように前回書いたコードをロゴ抜きで移植し、
前回までは
でしたが、今回は
にアクセスしてみましょう。
<template>
<main class="container mt-5">
<div class="row">
<div class="col-12 text-right mb-4">
<div class="d-flex justify-content-between">
<h3>商品一覧</h3>
<!-- <nuxt-link to="/items/add" class="btn btn-info">
商品を追加する
</nuxt-link> -->
</div>
</div>
<template v-for="item in items">
<div :key="item.id" class="col-lg-3 col-md-4 col-sm-6 mb-4">
<!--<item-card :on-delete="deleteitem" :item="item" />-->
</div>
</template>
</div>
</main>
</template>
<script>
import ItemCard from '~/components/ItemCard.vue'
export default {
components: {
ItemCard
},
async asyncData ({ $axios, params }) {
try {
const items = await $axios.$get('items/')
return { items }
} catch (e) {
return { items: [] }
}
},
data () {
return {
items: []
}
},
head () {
return {
title: '商品一覧'
}
}
}
</script>
するとこんな感じです。Vuetifyのロゴ入りの時よりもそれらしくなりましたね。
続いては詳細をクリックした時にきちんとそのページの説明文など詳細な説明が出るようにしましょう。
以下のように書いてみます。
<template>
<main class="container my-5">
<div class="row">
<div class="col-12 text-center my-3">
<h2 class="mb-3 display-4 text-uppercase">
{{ item.name }}
</h2>
</div>
<div class="col-md-6 mb-4">
<img
class="img-fluid"
style="width: 400px; border-radius: 10px; box-shadow: 0 1rem 1rem rgba(0,0,0,.7);"
:src="item.image"
alt
>
</div>
<div class="col-md-6">
<div class="item-details">
<h4>カテゴリー</h4>
<p>{{ item.category }}</p>
<h4>値段</h4>
<p>{{ item.price }}</p>
<h4>説明</h4>
<p>{{ item.description }}</p>
</div>
</div>
</div>
</main>
</template>
<script>
export default {
async asyncData ({ $axios, params }) {
try {
const item = await $axios.$get(`/items/${params.id}`)
return { item }
} catch (e) {
return { item: [] }
}
},
data () {
return {
item: {
id:'',
name:'',
image:'',
price:'',
description:'',
}
}
},
head () {
return {
title: '商品詳細'
}
}
}
</script>
<style scoped>
</style>
そして詳細をクリックするとこんな感じです。
一覧のページでは読めなかった説明が読めますね。
こういった感じに商品一覧のページでは必要最低限の情報を取得し、各idごとのページではより詳細な情報を取得し、表示する、といったような使い分けをします。
詳細ページの作り方についてはこれくらいで終わりです。
次回はPOST編です。
※追記
書きました!
Nuxt&Django REST FrameworkでCRUD POST編