174 lines
3.6 KiB
Vue
174 lines
3.6 KiB
Vue
<template>
|
|
<section>
|
|
<section>
|
|
<h2>
|
|
{{ post.title }}
|
|
</h2>
|
|
<small>
|
|
<span>
|
|
by
|
|
<a
|
|
v-if="theme.author.url"
|
|
:href="theme.author.url"
|
|
target="_blank"
|
|
rel="noopener"
|
|
>
|
|
{{ theme.author.name }}
|
|
</a>
|
|
<span v-else>
|
|
{{ theme.author.name }}
|
|
</span>
|
|
</span>
|
|
<span v-if="post.date" style="float: right">
|
|
{{ post.date | formatDate }}
|
|
</span>
|
|
</small>
|
|
</section>
|
|
|
|
<section v-html="post.contentHtml"></section>
|
|
|
|
<section class="tags-container">
|
|
<span>Tags:</span>
|
|
<span v-for="t in post.tag || []" :key="t">
|
|
<nuxt-link :to="`/tag/${t}`">
|
|
{{ t }}
|
|
</nuxt-link>
|
|
</span>
|
|
</section>
|
|
|
|
<footer v-if="remark42settings">
|
|
<div ref="remark42" />
|
|
</footer>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Vue, Component, Watch } from 'nuxt-property-decorator'
|
|
import { THEME } from '~/assets/global'
|
|
import '~/assets/remark42'
|
|
|
|
@Component<PostPage>({
|
|
async asyncData({ $axios, params }) {
|
|
const r = await $axios.$get('/api', {
|
|
params: {
|
|
path: params.pathMatch,
|
|
},
|
|
})
|
|
|
|
return {
|
|
post: r,
|
|
}
|
|
},
|
|
head() {
|
|
const { title: _title, content, tag, image } = this.post
|
|
const title = `${_title} - ${THEME.title}`
|
|
const description = content.substr(0, 140)
|
|
|
|
return {
|
|
title,
|
|
meta: [
|
|
{
|
|
hid: 'description',
|
|
name: 'description',
|
|
content: description,
|
|
},
|
|
...(tag
|
|
? [
|
|
{
|
|
hid: 'keywords',
|
|
name: 'keywords',
|
|
content: tag.join(','),
|
|
},
|
|
]
|
|
: []),
|
|
{
|
|
hid: 'og:title',
|
|
property: 'og:title',
|
|
content: title,
|
|
},
|
|
{
|
|
hid: 'og:description',
|
|
property: 'og:description',
|
|
content: description,
|
|
},
|
|
{
|
|
hid: 'twitter:title',
|
|
property: 'twitter:title',
|
|
content: title,
|
|
},
|
|
{
|
|
hid: 'twitter:description',
|
|
property: 'twitter:description',
|
|
content: description,
|
|
},
|
|
...(image
|
|
? [
|
|
{
|
|
hid: 'og:image',
|
|
property: 'og:image',
|
|
content: image,
|
|
},
|
|
{
|
|
hid: 'twitter:image',
|
|
property: 'twitter:image',
|
|
content: image,
|
|
},
|
|
]
|
|
: []),
|
|
],
|
|
}
|
|
},
|
|
mounted() {
|
|
this.initRemark42()
|
|
},
|
|
beforeDestroy() {
|
|
if (this.remark42Instance) {
|
|
this.remark42Instance.destroy()
|
|
}
|
|
},
|
|
})
|
|
export default class PostPage extends Vue {
|
|
post!: {
|
|
date?: string
|
|
title: string
|
|
image?: string
|
|
tag?: string[]
|
|
category?: string[]
|
|
content: string
|
|
}
|
|
|
|
theme = THEME
|
|
|
|
remark42settings = THEME.comment?.remark42 || null
|
|
remark42Instance: any = null
|
|
|
|
@Watch('$route.params.pathMatch')
|
|
initRemark42() {
|
|
this.$nextTick(() => {
|
|
if (
|
|
this.$refs.remark42 &&
|
|
process.browser &&
|
|
this.remark42settings &&
|
|
window.REMARK42
|
|
) {
|
|
if (this.remark42Instance) {
|
|
this.remark42Instance.destroy()
|
|
}
|
|
|
|
this.remark42Instance = window.REMARK42.createInstance({
|
|
node: this.$refs.remark42 as HTMLElement,
|
|
host: this.remark42settings.host,
|
|
site_id: this.remark42settings.siteId,
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.tags-container > span + span {
|
|
margin-left: 0.6em;
|
|
}
|
|
</style>
|