เนื้อหาของบทเรียน Nuxt.js
- ตอนที่ 1 - Getting Started with Nuxt.js
- ตอนที่ 2 - สร้าง Nuxt.js ด้วย create-nuxt-app
- ตอนที่ 3 - การกำหนด Routing
- ตอนที่ 4 - Nuxt.js Concept
- ตอนที่ 5 - Nuxt Content และ Async Data
- ตอนที่ 6 - การดึงข้อมูลจาก APIs
- ตอนที่ 7 - การใช้งานร่วมกับ Vuex Store
- ตอนที่ 8 - ทำระบบ Authentication ด้วย Nuxt.js
- ตอนที่ 9 - การ Deploy Nuxt.js
- ตอนที่ 10 - การทำ Internal API และ Middleware
- ตอนที่ 11 - ทำ SEO และ Meta tags
- ตอนที่ 12 - Workshop
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 Worlddescription: 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.comtitle: Devahoyหรือไฟล์ /content/data.csv
id, name, age1, John Doe, 252, Jane Doe, 23Output ที่ได้ ก็คล้ายๆ กับ 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 ยังไงดี?
อ่านบทถัดไป 👉 ตอนที่ 6 - การดึงข้อมูลจาก APIs
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust