Files
zhdiary/packages/web/components/PostQuery.vue
T
2019-12-25 00:11:26 +07:00

89 lines
2.1 KiB
Vue

<template lang="pug">
section
section.m-lg(v-if="tag")
h2.title.is-2
span.mr-sm Tag:
span(style="font-weight: 400") {{tag}}
section(v-if="posts && posts.length > 0")
post-teaser(v-for="p in posts" :header="p" :key="p.name")
b-pagination.my-lg.mx-sm(:current.sync="page" :total="count" :per-page="perPage"
icon-prev="caret-left" icon-next="caret-right" size="default" rounded)
div(v-else-if="posts")
empty
div(v-else)
</template>
<script lang="ts">
import PostTeaser from './PostTeaser.vue'
import Empty from './Empty.vue'
import QParser from 'q2filter'
import { normalizeArray, searchPosts } from '@/assets/util'
import { Vue, Component, Prop, Watch } from 'nuxt-property-decorator'
import { globalStore } from '../store'
@Component({
components: {
PostTeaser,
Empty,
},
})
export default class PostQuery extends Vue {
@Prop({ default: '' }) q!: string
@Prop({ default: '' }) tag!: string
@Prop({ required: true }) defaults!: {
count: number
posts: any[]
}
count = this.defaults.count
posts: any[] = this.defaults.posts
perPage = 5
get page () {
return parseInt(normalizeArray(this.$route.query.page) || '1')
}
set page (p) {
const { page, ...query } = this.$route.query
if (p === 1) {
this.$router.push({ query })
} else {
this.$router.push({
query: {
...query,
page: p.toString(),
},
})
}
}
mounted () {
this.updatePosts()
}
@Watch('page')
@Watch('q')
@Watch('tag')
async updatePosts () {
const ps = await Promise.all(searchPosts({
q: this.tag ? {
tag: this.tag,
} : this.q,
current: true,
posts: await fetch(`/build/header/posts.json?h=${globalStore.hash.posts._header}`).then((r) => r.json()),
}).map(async (h) => {
if (!h.teaser) {
h.teaser = await fetch(`/build/teaser/${h.path}?h=${globalStore.hash.posts[h.path]}`).then((r) => r.text())
}
return h
}))
this.count = ps.length
this.posts = ps.filter((p, i) => {
const iPage = i / this.perPage
return iPage >= this.page - 1 && iPage < this.page
})
}
}
</script>