From 05fc69386dd09107d8c22b4e908eacfe02097203 Mon Sep 17 00:00:00 2001 From: Konkamon Sion Date: Tue, 17 Sep 2024 20:00:13 +0700 Subject: [PATCH] feat(Blog): :zap: Implement Caching by using 'useNuxtData' / Improved Alert --- components/Blog/TagsDisplay.vue | 18 +++++++- nuxt.config.ts | 2 +- pages/blog/[slug].vue | 19 +++++++-- pages/blog/index.vue | 73 +++++++++++++++++++-------------- 4 files changed, 77 insertions(+), 35 deletions(-) diff --git a/components/Blog/TagsDisplay.vue b/components/Blog/TagsDisplay.vue index d1c87d4..1236071 100644 --- a/components/Blog/TagsDisplay.vue +++ b/components/Blog/TagsDisplay.vue @@ -16,6 +16,22 @@ interface tagsItem { id: string name: string } +const nuxt = useNuxtApp() const { find } = useStrapi() -const { data: tagItems } = await useLazyAsyncData('tags', () => find('categories', { fields: ['name'], sort: 'name:asc' })) +const { data: tagItems } = useNuxtData('tags') +const { data } = await useLazyAsyncData('tags', () => find('categories', { fields: ['name'], sort: 'name:asc' }), { + default() { + return tagItems.value + }, + getCachedData: (key) => { + if (nuxt.isHydrating && nuxt.payload.data[key]) { + return nuxt.payload.data[key] + } + if (nuxt.static.data[key]) { + return nuxt.static.data[key] + } + return null + }, + deep: false +}) diff --git a/nuxt.config.ts b/nuxt.config.ts index 017dfa2..1192eef 100755 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -9,7 +9,7 @@ export default defineNuxtConfig({ routeRules: { '/': { prerender: true }, '/blog': { isr: true }, - '/blog/**': { isr: true } + '/blog/**': { isr: true, cache: { maxAge: 60 * 60 * 24 * 7 } } }, modules: [ diff --git a/pages/blog/[slug].vue b/pages/blog/[slug].vue index d19ad7e..fc33168 100644 --- a/pages/blog/[slug].vue +++ b/pages/blog/[slug].vue @@ -29,6 +29,7 @@ import type { RouteLocationNormalized } from 'vue-router' import type { StrapiBlogSlug } from '~/types/StrapiBlogSlug' + const { findOne } = useStrapi() const route: RouteLocationNormalized = useRoute() const nuxt = useNuxtApp() @@ -48,7 +49,16 @@ const { data: blogSlug } = await useAsyncData( }).then((data) => data.data.attributes), { watch: false, - deep: false + deep: false, + getCachedData: (key) => { + if (nuxt.isHydrating && nuxt.payload.data[key]) { + return nuxt.payload.data[key] + } + if (nuxt.static.data[key]) { + return nuxt.static.data[key] + } + return null + }, } ) @@ -65,8 +75,8 @@ useSeoMeta({ definePageMeta({ middleware: ['check-blog-post'] }) - -const { data: ast, status } = await useAsyncData('markdown', () => parseMarkdown(blogSlug.value?.content as string), { +const { data: ast } = useNuxtData('markdown') +const { status } = await useAsyncData('markdown', () => parseMarkdown(blogSlug.value?.content as string), { getCachedData: (key) => { if (nuxt.isHydrating && nuxt.payload.data[key]) { return nuxt.payload.data[key] @@ -76,6 +86,9 @@ const { data: ast, status } = await useAsyncData('markdown', () => parseMarkdown } return null }, + default(){ + return ast.value + }, watch: false, deep: false, server: false, diff --git a/pages/blog/index.vue b/pages/blog/index.vue index f6b2c8d..e3a2a2b 100644 --- a/pages/blog/index.vue +++ b/pages/blog/index.vue @@ -56,30 +56,13 @@ /> - - - - @@ -88,6 +71,7 @@ useMySlugCacheStore() import { type StrapiBlogs } from '~/types/StrapiBlogs' +import type { AlertColor, AlertVariant } from '#ui/types' const { find } = useStrapi() const loading = ref(false) @@ -98,6 +82,7 @@ const toast = useToast() const nuxt = useNuxtApp() const currentPage = ref(1) const pageSize = 6 +const { data: blogsData } = useNuxtData('allBlogsWithSearch') const constructSearchFilters = (searchInput: string) => { const keywords = searchInput.split(' ') const filters = keywords.map((keyword) => ({ @@ -105,12 +90,7 @@ const constructSearchFilters = (searchInput: string) => { })) return { $and: filters } } -const { - data: blogsData, - status, - error, - refresh -} = await useAsyncData( +const { data, status, error, refresh } = await useAsyncData( 'allBlogsWithSearch', () => find('blogs', { @@ -132,6 +112,7 @@ const { }), { deep: false, + lazy: true, watch: [currentPage], getCachedData(key) { if (nuxt.isHydrating && nuxt.payload.data[key]) { @@ -141,6 +122,9 @@ const { return nuxt.static.data[key] } return null + }, + default() { + return blogsData.value } } ) @@ -191,4 +175,33 @@ defineShortcuts({ } } }) + +const alertConfig = computed(() => { + if (status.value === 'pending') { + return { + title: 'Loading', + description: 'กำลังค้นหา Blog กรุณารอสักครู่', + icon: 'ph:magnifying-glass-duotone', + color: 'primary' as AlertColor, + variant: 'soft' as AlertVariant + } + } else if (blogsData.value?.meta.pagination.total === 0 && status.value === 'success') { + return { + title: 'ไม่พบ Blogs', + description: `ไม่พบ Blogs จากคำค้นหา ${searchInput.value}`, + icon: 'ic:round-search-off', + color: 'orange' as AlertColor, + variant: 'subtle' as AlertVariant + } + } else if (error.value?.statusCode || status.value === 'error') { + return { + title: 'Error', + description: 'เกิดข้อผิดพลาดในการโหลดข้อมูล กรุณาลองใหม่อีกครั้งในภายหลัง', + icon: 'ph:magnifying-glass-duotone', + color: 'red' as AlertColor, + variant: 'subtle' as AlertVariant + } + } + return null +})