- Nuxt.js Fundamental ตอนที่ 0 - พื้นฐานการเขียนเว็บด้วย Nuxt.js
- Nuxt.js Fundamental ตอนที่ 1 - เริ่มต้นกับ Nuxt.js
- Nuxt.js Fundamental ตอนที่ 2 - สร้าง Nuxt.js ด้วย create-nuxt-app
- Nuxt.js Fundamental ตอนที่ 3 - การกำหนด Routing
- Nuxt.js Fundamental ตอนที่ 4 - Nuxt.js Concept
- Nuxt.js Fundamental ตอนที่ 5 - Nuxt Content และ Async Data
- Nuxt.js Fundamental ตอนที่ 6 - การ Fetch ข้อมูลจาก API
- Nuxt.js Fundamental ตอนที่ 7 - การใช้งานร่วมกับ Vuex Store
- Nuxt.js Fundamental ตอนที่ 8 - การทำระบบ Authentication
- Nuxt.js Fundamental ตอนที่ 9 - การ Deploy Nuxt.js
- Nuxt.js Fundamental ตอนที่ 10 - การทำ Internal API และ Middleware
- Nuxt.js Fundamental ตอนที่ 11 - ทำ SEO และ Meta tags
- Nuxt.js Fundamental ตอนที่ 12 - ทำ Workshop เว็บ Portfolio
Nuxt.js Fundamental ตอนที่ 5 - Nuxt Content และ Async Data
เขียนวันที่ : Aug 22, 2020
(อัพเดท : Mar 19, 2022)
Nuxt Content คืออะไร?
Nuxt Content เป็น Module ที่ทำให้เราสามารถที่จะอ่าน JSON, YAML, Markdown หรือ CSV ใน folder content
เหมือนกับการใช้พวก MongoDB API หรือเป็น QueryBuilder API นั่นเอง
ข้อดีของ Nuxt Content คือ
- เร็วและรองรับ hot reload ในการ development
- รองรับ Full-text search
- เขียน Vue Components ใน Markdown ได้
- QueryBuilder API อารมณ์คล้ายๆ MongoDB API
- รองรับหลาย format ดังที่กล่าวไป CSV, YAML, JSON, XML, Markdown
วิธีการใช้งาน Nuxt Content
ก็เพียงแค่ install ผ่าน NPM หรือ yarn ได้เลยครับ
npm install @nuxt/content
จากนั้นที่ไฟล์ nuxt.config.js
ก็ไปเพิ่ม @nuxt/content
ไปในส่วนของ modules
modules: [
'@nuxt/content'
]
}
วิธีการทำงานของ Nuxt Content คือ
- อ่านค่าจาก raw data (แล้วแต่ format เป็นอะไร)
- ตัว Nuxt จะ transform raw data เป็นรูปแบบ JSON tree
- ใช้
$content
ในการ fetch data เพื่อมาแสดง (รองรับ async/await) - แสดงผลด้วยการใช้
<nuxt-content>
Component (เฉพาะ Markdown)
เริ่มต้นเขียน Content
ลองด้วย Markdown ก่อนครับ สร้างไฟล์ hello.md
ใน folder /content/posts
ครับ
---
title: Hello World
description: Learn how to use @nuxt/content.
---
# Hello
This is <nuxt-link to="/">Home</nuxt-link>
This is paragraph
ซึ่ง Markdown ก็รองรับ Front matter ในรูปแบบ YAML (ใช้ - 3ตัว) ทำให้เรากำหนด key value เช่น title, description หรือจะเป็น published_date, author อะไรก็ได้
ทีนี้ ตัว Nuxt Content มันก็จะ generate ข้อมูลเป็น JSON tree หน้าตาประมาณนี้
{
body: Object
title: "Hello World"
description: "Learn how to use @nuxt/content."
dir: "/"
extension: ".md"
path: "/hello"
slug: "hello"
toc: Array
createdAt: DateTime
updatedAt: DateTime
}
ตัว
createdAt
และupdatedAt
จะใช้เวลาตอนสร้างไฟล์ แต่เราสามารถ override ได้ โดยการกำหนดค่าใน Front Matter
ดูข้อมูลเพิ่มเติม Nuxt Content - Writing Content
หรือ เราสามารถใช้ไฟล์ YAML หรือ jSON ก็ได้ เช่น ไฟล์ /content/site.yml
site: https://devahoy.com
title: Devahoy
หรือไฟล์ /content/data.csv
id, name, age
1, John Doe, 25
2, Jane Doe, 23
Output ที่ได้ ก็คล้ายๆ กับ Markdown เพียงแค่เปลี่ยน body
, extension
และก็ path
, slug
ตามชื่อไฟล์นั่นเอง
Output ของ YAML
{
'dir': '/',
'slug': 'site',
'path': '/site',
'extension': '.yml',
'site': 'https://devahoy.com',
'title': 'Devahoy'
}
Output ของ CSV
"dir": "/",
"slug": "data",
"path": "/data",
"extension": ".csv",
"body": [
{
"id": 1,
"name": "John Doe",
"age": 25
},
{
"id": 2,
"name": "Jane Doe",
"age": 23
}
]
}
การ Fetch ข้อมูล
ต่อมา เราจะ fetch data content กันนะครับ โดย Nuxt Content เราสามารถเรียกแบบ global ได้เลย ด้วย this.$content
และ พวก plugins, asyncData
, fetch
, middleware เราสามารถเรียกผ่าน context
ได้เลย เช่น context.$content
syntax ในการเรียกคือ
$content(path, options?)
path
- ถ้าเป็น file จะได้ result เป็น Object ถ้าเป็น folder จะเป็น Array
เช่น ผมจะดึงข้อมูลในไฟล์ /content/posts/hello.md
ผมก็เรียกแบบนี้
const post = await this.$content('posts/hello').fetch()
นอกจากนี้เรายังใช้พวก where
, limit
, sortBy
, only
ได้เช่น
const posts = await this.$content('posts')
.only(['title', 'createdAt'])
.sortBy('createdAt', 'asc')
.limit(5)
.skip(10)
.where({
isArchived: false
})
.search('welcome')
.fetch();
รายละเอียดเพิ่มเติม Nuxt Content - Fetching Content
ตัวอย่าง เช่น ผมจะดึงข้อมูล /content/site.yml
มาแสดงใน pages/site.vue
โดยผมใช้ $content
ใน function asyncData
นั่นเอง
<template>
<h1>Ahoy!</h1>
<p>Site : {{ site.site }}</p>
<p>Title: {{ site.title }}</p>
</template>
<script>
export default {
async asyncData({ $content }) {
const site = await $content('site').fetch();
return {
site
};
}
};
</script>
การแสดงผล Content สำหรับ Markdown
สำหรับ Markdown มันค่อนข้างแตกต่างจากไฟล์อื่นนิดหน่อย เพราะมันต้อง Transform markdown เป็น HTML body แล้วเก็บอยู่ใน object ของ JSON ฉะนั้น เวลาแสดงผลใน Vue Component ก็เลยต้องใช้ <nuxt-content
นั่นเอง ตัวอย่างเช่น
ไฟล์ /pages/hello.vue
<article>
<h1>{{ post.title }}</h1>
<nuxt-content :document="post" />
</article>
</template>
<script>
export default {
async asyncData ({ $content }) {
const post = await $content('posts/hello').fetch()
return {
post
}
}
}
</script>
เรื่อง CSS นิดหน่อย <nuxt-content>
จะทำการเพิ่มคลาส .nuxt-content
ให้เราอัตโนมัติ ทีนี้ ถ้าใครอยาก override หรือปรับ css ก็ต้องใช้ selecotr แบบนี้ครับ
.nuxt-content h1 {
/* my custom h1 style */
}
Hints & Questions?
- เอ๊ะ แล้วถ้าเราอยากทำเป็นคล้ายๆ Blog โดยสร้างจากไฟล์ Markdown สมมติ มี 10 ไฟล์ และต้องมาสร้างเพจ
pages/**.vue
อีก 10 ไฟล์ด้วยรึเปล่านะ? เราจะทำ dynamic route ยังไงดี? ลองคิด และลองประยุกต์ใช้กันดูนะครับ :) - ลองเล่น QueryBuilder API เช่น เราอยาก query โดยกำหนดเงื่อนไข
.where()
หรือกำหนด sortBy ยังไงดี?