11<script setup>
2+ import { watch } from ' vue'
3+ import { useRoute , useRouter } from ' vue-router'
4+
25useHead ({
36 title: ' Blog - Python Cheatsheet' ,
47 meta: [
@@ -11,6 +14,16 @@ useHead({
1114})
1215
1316const router = useRouter ()
17+ const route = useRoute ()
18+ const currentPage = ref (parseInt (route .query .page ) || 1 )
19+ const postsPerPage = 7
20+
21+ watch (
22+ () => route .query .page ,
23+ (newPage ) => {
24+ currentPage .value = parseInt (newPage) || 1
25+ },
26+ )
1427
1528const articles = computed (() => {
1629 const routes = router .options .routes
@@ -25,27 +38,62 @@ const articles = computed(() => {
2538 })
2639})
2740
28- const latestArticle = computed (() => articles .value [0 ])
29- const otherArticles = computed (() => articles .value .slice (1 ))
41+ const totalPages = computed (() => {
42+ return Math .ceil (articles .value .length / postsPerPage)
43+ })
44+
45+ const postsToShow = computed (() => {
46+ const start = (currentPage .value - 1 ) * postsPerPage
47+ const end = start + postsPerPage
48+ return articles .value .slice (start, end)
49+ })
50+
51+ const featuredArticle = computed (() => {
52+ return currentPage .value === 1 ? postsToShow .value [0 ] : null
53+ })
54+
55+ const gridArticles = computed (() => {
56+ if (currentPage .value === 1 ) {
57+ return postsToShow .value .slice (1 )
58+ }
59+ return postsToShow .value
60+ })
3061
3162const getTags = (article ) => {
3263 const tags = article .children [0 ]? .meta ? .tags
3364 if (! tags) return []
3465 return tags .split (' ,' ).map ((tag ) => tag .trim ())
3566}
67+
68+ function updatePage (newPage ) {
69+ currentPage .value = newPage
70+ router .push ({ query: { page: newPage } })
71+ }
72+
73+ function nextPage () {
74+ if (currentPage .value < totalPages .value ) {
75+ updatePage (currentPage .value + 1 )
76+ }
77+ }
78+
79+ function prevPage () {
80+ if (currentPage .value > 1 ) {
81+ updatePage (currentPage .value - 1 )
82+ }
83+ }
3684< / script>
3785
3886< template>
39- < div v- if = " latestArticle " class = " mb-12" >
87+ < div v- if = " featuredArticle " class = " mb-12" >
4088 < router- link
41- : to= " latestArticle .path"
89+ : to= " featuredArticle .path"
4290 class = " group block overflow-hidden rounded-lg border border-slate-200 bg-white shadow-md transition-all duration-300 hover:shadow-xl dark:border-slate-700 dark:bg-slate-800"
4391 >
4492 < div class = " md:flex" >
4593 < div class = " relative md:w-1/2" >
4694 < img
47- v- if = " latestArticle .children[0]?.meta?.socialImage"
48- : src= " latestArticle .children[0]?.meta?.socialImage"
95+ v- if = " featuredArticle .children[0]?.meta?.socialImage"
96+ : src= " featuredArticle .children[0]?.meta?.socialImage"
4997 alt= " "
5098 class = " h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
5199 / >
@@ -72,22 +120,25 @@ const getTags = (article) => {
72120 < div class = " flex flex-col p-6 md:w-1/2" >
73121 < div class = " flex-1" >
74122 < div class = " mb-2 flex flex-wrap gap-2" >
75- < Tag v- for = " tag in getTags(latestArticle).slice(0, 2)" : key= " tag" >
123+ < Tag
124+ v- for = " tag in getTags(featuredArticle).slice(0, 2)"
125+ : key= " tag"
126+ >
76127 {{ tag }}
77128 < / Tag>
78129 < / div>
79130 < h2
80131 class = " text-2xl font-semibold text-slate-800 dark:text-slate-100"
81132 >
82- {{ latestArticle .children [0 ]? .meta ? .title }}
133+ {{ featuredArticle .children [0 ]? .meta ? .title }}
83134 < / h2>
84135 < p class = " mt-2 text-slate-600 dark:text-slate-400" >
85- {{ latestArticle .children [0 ]? .meta ? .description }}
136+ {{ featuredArticle .children [0 ]? .meta ? .description }}
86137 < / p>
87138 < / div>
88139 < div class = " mt-4 flex items-center justify-between" >
89140 < time class = " text-sm text-slate-500 dark:text-slate-400" >
90- {{ latestArticle .children [0 ]? .meta ? .date }}
141+ {{ featuredArticle .children [0 ]? .meta ? .date }}
91142 < / time>
92143 < div class = " flex items-center text-sm font-medium text-sky-500" >
93144 Read article
@@ -113,7 +164,7 @@ const getTags = (article) => {
113164
114165 < div class = " grid gap-8 sm:grid-cols-2 lg:grid-cols-3" >
115166 < router- link
116- v- for = " article in otherArticles "
167+ v- for = " article in gridArticles "
117168 : key= " article.path"
118169 : to= " article.path"
119170 class = " group flex flex-col overflow-hidden rounded-lg border border-slate-200 bg-white shadow-md transition-all duration-300 hover:shadow-xl dark:border-slate-700 dark:bg-slate-800"
@@ -183,6 +234,13 @@ const getTags = (article) => {
183234 < / div>
184235 < / router- link>
185236 < / div>
237+
238+ < BlogPagination
239+ : current- page= " currentPage"
240+ : total- pages= " totalPages"
241+ @prev- page= " prevPage"
242+ @next- page= " nextPage"
243+ / >
186244< / template>
187245
188246< route lang= " yaml" >
0 commit comments