basic ui
This commit is contained in:
1 parent
3bc2a943bd
commit
e3fbe853df
12 files changed
+277
-50
No files matched your search
@@ -1,4 +1,5 @@
|
|||||||
*.*
|
*.*
|
||||||
!*.js
|
!*.js
|
||||||
!*.ts
|
!*.ts
|
||||||
|
!*.vue
|
||||||
node_modules
|
node_modules
|
||||||
+2
-5
@@ -3,7 +3,7 @@
|
|||||||
"tabs": [
|
"tabs": [
|
||||||
{
|
{
|
||||||
"name": "千字文",
|
"name": "千字文",
|
||||||
"to": "/posts/千字文"
|
"to": "posts/2019/08/千字文"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Resources",
|
"name": "Resources",
|
||||||
@@ -14,8 +14,5 @@
|
|||||||
"url": "https://github.com/patarapolw/zhdiary"
|
"url": "https://github.com/patarapolw/zhdiary"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"fullUrl": "https://zhdiary.polvcode.dev",
|
"fullUrl": "https://zhdiary.polvcode.dev"
|
||||||
"author": {
|
|
||||||
"name": "Pacharapol Withayasakpunt"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -47,6 +47,8 @@ const db = new DataStore('assets/data.nedb')
|
|||||||
...data,
|
...data,
|
||||||
date: formatDate(data.date),
|
date: formatDate(data.date),
|
||||||
filename: f,
|
filename: f,
|
||||||
|
type,
|
||||||
|
slug: f.replace(/^slides\//, '').replace(/\.md$/, ''),
|
||||||
h,
|
h,
|
||||||
excerpt: computedExcerpt,
|
excerpt: computedExcerpt,
|
||||||
slides
|
slides
|
||||||
@@ -66,14 +68,19 @@ const db = new DataStore('assets/data.nedb')
|
|||||||
computedContent = computedContent.substr(computedExcerpt.length)
|
computedContent = computedContent.substr(computedExcerpt.length)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.date) {
|
|
||||||
console.log(formatDate(data.date))
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.insert({
|
await db.insert({
|
||||||
...data,
|
...data,
|
||||||
date: formatDate(data.date),
|
date: formatDate(data.date),
|
||||||
filename: f,
|
filename: f,
|
||||||
|
type: f.split('/')[0],
|
||||||
|
slug: f.startsWith('posts/blog/')
|
||||||
|
? f.replace(/^posts\/blog\//, '').replace(/\.md$/, '')
|
||||||
|
: f.startsWith('posts/')
|
||||||
|
? (() => {
|
||||||
|
const ff = f.split('/')
|
||||||
|
return ff[ff.length - 1].replace(/\.md$/, '')
|
||||||
|
})()
|
||||||
|
: f.replace(/^[^/]+?\//, '').replace(/\.md$/, ''),
|
||||||
h,
|
h,
|
||||||
excerpt: computedExcerpt,
|
excerpt: computedExcerpt,
|
||||||
remaining: computedContent
|
remaining: computedContent
|
||||||
|
|||||||
@@ -24,30 +24,30 @@ dataRouter.get('/*', (req, res) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
dataRouter.post('/', async (req, res, next) => {
|
dataRouter.post('/:type', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const { q, cond = {}, project, offset, limit } = req.body
|
const { q, cond = {}, project, offset, limit } = req.body
|
||||||
const $and = [
|
const $and = [
|
||||||
{ filename: { $regex: /^posts\// } },
|
{ type: req.params.type },
|
||||||
cond
|
cond
|
||||||
] as any[]
|
]
|
||||||
|
|
||||||
if (q) {
|
if (q) {
|
||||||
const parser = new QSearch({
|
const parser = new QSearch({
|
||||||
dialect: 'nedb',
|
dialect: 'nedb',
|
||||||
schema: {
|
schema: {
|
||||||
title: {},
|
title: {},
|
||||||
filename: {},
|
slug: {},
|
||||||
excerpt: {},
|
excerpt: {},
|
||||||
date: { type: 'date' }
|
date: { type: 'date' }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
$and.push(parser.parse(q))
|
$and.push(parser.parse(q).cond)
|
||||||
}
|
}
|
||||||
|
|
||||||
const count = await db.count({ $and })
|
const count = await db.count({ $and })
|
||||||
|
|
||||||
let c = db.find({ $and }, project).skip(offset || 0)
|
let c = db.find({ $and }, project).sort({ date: -1 }).skip(offset || 0)
|
||||||
|
|
||||||
if (limit !== null) {
|
if (limit !== null) {
|
||||||
c = c.limit(limit || 5)
|
c = c.limit(limit || 5)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ export default class MakeHtml {
|
|||||||
})
|
})
|
||||||
|
|
||||||
constructor (public id = 'el-' + Math.random().toString(36).substr(2)) {
|
constructor (public id = 'el-' + Math.random().toString(36).substr(2)) {
|
||||||
|
this.md.setFlavor('github')
|
||||||
|
|
||||||
this.md.addExtension({
|
this.md.addExtension({
|
||||||
type: 'lang',
|
type: 'lang',
|
||||||
filter (text) {
|
filter (text) {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
.container.m-md
|
||||||
|
h4.title.is-4 Sorry, but no post can be found.
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Vue, Component } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class Empty extends Vue {}
|
||||||
|
</script>
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
.post-meta.mb-sm
|
.post-meta(style="margin-bottom: 0.5em;")
|
||||||
.post-meta-author
|
.post-meta-author(v-if="author")
|
||||||
a.mr-md(:href="author.link" style="width: 24px; min-width: 24px"): img(:src="author.avatar" style="border-radius: 50%;")
|
a(:href="author.link" style="width: 24px; min-width: 24px")
|
||||||
a.mr-md(:href="author.link") {{author.login}}
|
img(:src="author.avatar" style="border-radius: 50%; margin-right: 1em;")
|
||||||
|
a.mr-md(:href="author.link" style="margin-right: 1em;") {{author.login}}
|
||||||
div(style="flex-grow: 1")
|
div(style="flex-grow: 1")
|
||||||
div {{dateString}}
|
div {{dateString}}
|
||||||
</template>
|
</template>
|
||||||
@@ -17,10 +18,10 @@ import { config } from '../global'
|
|||||||
export default class PostHeader extends Vue {
|
export default class PostHeader extends Vue {
|
||||||
@Prop({ required: true }) header!: any
|
@Prop({ required: true }) header!: any
|
||||||
|
|
||||||
author = config.author || {}
|
author = config.author
|
||||||
|
|
||||||
get dateString () {
|
get dateString () {
|
||||||
return this.header.date ? dayjs(this.header.date).format("ddd D MMMM YYYY") : ''
|
return this.header.date ? dayjs(this.header.date).format('ddd D MMMM YYYY') : ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
.card.my-lg.blog-post
|
.card.blog-post(style="margin-top: 1em; margin-bottom: 1em")
|
||||||
.card-content
|
.card-content
|
||||||
PostHeader(:header="header")
|
PostHeader(:header="header")
|
||||||
.post-content
|
.post-content
|
||||||
@@ -25,7 +25,7 @@ export default class PostTeaser extends Vue {
|
|||||||
@Prop({ required: true }) header!: any
|
@Prop({ required: true }) header!: any
|
||||||
|
|
||||||
get url () {
|
get url () {
|
||||||
return this.header.filename.replace(/\.md$/, '')
|
return 'posts/' + this.header.slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -36,10 +36,12 @@ export default class PostTeaser extends Vue {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
max-width: 80vw;
|
max-width: 80vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-content {
|
.post-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-teaser {
|
.image-teaser {
|
||||||
width: calc(100% + 3rem);
|
width: calc(100% + 3rem);
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
@@ -47,6 +49,7 @@ export default class PostTeaser extends Vue {
|
|||||||
margin-left: -1.5rem;
|
margin-left: -1.5rem;
|
||||||
margin-right: -1.5rem;
|
margin-right: -1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 800px) {
|
@media only screen and (min-width: 800px) {
|
||||||
.image-teaser {
|
.image-teaser {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -55,6 +58,7 @@ export default class PostTeaser extends Vue {
|
|||||||
float: right;
|
float: right;
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-content {
|
.post-content {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ section
|
|||||||
:target="t.to ? '' : '_blank'"
|
:target="t.to ? '' : '_blank'"
|
||||||
) {{t.name}}
|
) {{t.name}}
|
||||||
template(slot="end")
|
template(slot="end")
|
||||||
form.field.m-sm.px-md(@submit.prevent="onSearch")
|
form.field.m-sm.px-md(@submit.prevent="onSearch" style="margin: 0.4rem; padding-left: 0.5rem; padding-right: 0.5rem")
|
||||||
.control.has-icons-right
|
.control.has-icons-right
|
||||||
input.input.is-rounded(type="search" placeholder="Search" v-model="q")
|
input.input.is-rounded(type="search" placeholder="Search" v-model="q")
|
||||||
span.icon.is-right
|
span.icon.is-right
|
||||||
@@ -34,20 +34,21 @@ import { normalizeArray } from '../utils'
|
|||||||
|
|
||||||
@Component<DefaultLayout>({
|
@Component<DefaultLayout>({
|
||||||
metaInfo () {
|
metaInfo () {
|
||||||
const url = this.config.fullUrl + this.$route.path;
|
const url = this.config.fullUrl + this.$route.path
|
||||||
return {
|
return {
|
||||||
|
titleTemplate: '%s - ZhDiary',
|
||||||
link: [
|
link: [
|
||||||
{
|
{
|
||||||
rel: 'canonical',
|
rel: 'canonical',
|
||||||
href: url,
|
href: url
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: 'og:url',
|
hid: 'og:url',
|
||||||
property: 'og:url',
|
property: 'og:url',
|
||||||
content: url
|
content: url
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,15 +58,16 @@ export default class DefaultLayout extends Vue {
|
|||||||
q = ''
|
q = ''
|
||||||
|
|
||||||
mounted () {
|
mounted () {
|
||||||
this.q = normalizeArray(this.$route.query.q) || "";
|
this.q = normalizeArray(this.$route.query.q) || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearch () {
|
onSearch () {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: "/",
|
path: '/',
|
||||||
query: {
|
query: {
|
||||||
q: this.q
|
q: this.q
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ const router = new VueRouter({
|
|||||||
meta: {
|
meta: {
|
||||||
layout: 'default'
|
layout: 'default'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/posts/*',
|
||||||
|
component: () => import('../views/PostView.vue'),
|
||||||
|
meta: {
|
||||||
|
layout: 'default'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
section
|
||||||
|
.blog-post(v-if="post.excerpt")
|
||||||
|
.card(style="margin-top: 1rem; margin-bottom: 1rem;")
|
||||||
|
.card-content.content
|
||||||
|
PostHeader(:header="post")
|
||||||
|
h1.title {{post.title}}
|
||||||
|
.image-full(v-if="post.image")
|
||||||
|
img(:src="post.image" :alt="post.title")
|
||||||
|
div(v-html="post.excerpt + post.remaining")
|
||||||
|
div(style="word-break: break-word")
|
||||||
|
span(style="margin-right: 0.5rem;") Tag:
|
||||||
|
span(v-for="t in post.tag || []" :key="t" style="margin-right: 0.5rem;")
|
||||||
|
router-link(:to="'/tag/' + t") {{t}}
|
||||||
|
.card.my-lg
|
||||||
|
.card-content
|
||||||
|
vue-disqus(v-if="disqus" :shortname="disqus" :identifier="$route.path")
|
||||||
|
Empty(v-else)
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Vue, Component } from 'vue-property-decorator'
|
||||||
|
import { api } from '../utils'
|
||||||
|
import PostHeader from '../components/PostHeader.vue'
|
||||||
|
import Empty from '../components/Empty.vue'
|
||||||
|
|
||||||
|
@Component<PostView>({
|
||||||
|
components: {
|
||||||
|
PostHeader,
|
||||||
|
Empty
|
||||||
|
},
|
||||||
|
beforeRouteEnter ({ params }, from, next) {
|
||||||
|
api.post('/data/posts', {
|
||||||
|
cond: {
|
||||||
|
slug: params.pathMatch
|
||||||
|
},
|
||||||
|
limit: 1,
|
||||||
|
project: {
|
||||||
|
title: 1,
|
||||||
|
excerpt: 1,
|
||||||
|
remaining: 1,
|
||||||
|
date: 1,
|
||||||
|
tag: 1
|
||||||
|
}
|
||||||
|
}).then(({ data }) => {
|
||||||
|
next((vm) => {
|
||||||
|
vm.post = data.data[0] || {}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeRouteUpdate ({ query, params }, from, next) {
|
||||||
|
api.post('/data/posts', {
|
||||||
|
cond: {
|
||||||
|
slug: params.pathMatch
|
||||||
|
},
|
||||||
|
limit: 1,
|
||||||
|
project: {
|
||||||
|
title: 1,
|
||||||
|
excerpt: 1,
|
||||||
|
remaining: 1,
|
||||||
|
date: 1,
|
||||||
|
tag: 1
|
||||||
|
}
|
||||||
|
}).then(({ data }) => {
|
||||||
|
this.$set(this, 'post', data.data[0] || {})
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
metaInfo () {
|
||||||
|
const title = this.post.title
|
||||||
|
const description = (() => {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.innerHTML = this.post.excerpt
|
||||||
|
return div.innerText
|
||||||
|
})()
|
||||||
|
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
meta: [
|
||||||
|
{ vmid: 'description', name: 'description', content: description },
|
||||||
|
{
|
||||||
|
hid: 'og:title',
|
||||||
|
property: 'og:title',
|
||||||
|
content: this.post.title
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'og:description',
|
||||||
|
property: 'og:description',
|
||||||
|
content: description
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'og:image',
|
||||||
|
property: 'og:image',
|
||||||
|
content: this.post.image
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:title',
|
||||||
|
property: 'twitter:title',
|
||||||
|
content: this.post.title
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:description',
|
||||||
|
property: 'twitter:description',
|
||||||
|
content: description
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:image',
|
||||||
|
property: 'twitter:image',
|
||||||
|
content: this.post.image
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:card',
|
||||||
|
property: 'twitter:card',
|
||||||
|
content: 'summary_large_image'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default class PostView extends Vue {
|
||||||
|
post: any = {}
|
||||||
|
disqus = ''
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.image-full {
|
||||||
|
text-align: center;
|
||||||
|
margin: 1rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
min-width: 500px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.image-full {
|
||||||
|
margin-left: -1.5rem;
|
||||||
|
margin-right: -1.5rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
min-width: unset;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
section
|
section
|
||||||
section.m-lg(v-if="tag")
|
section(v-if="tag" style="margin: 1rem;")
|
||||||
h2.title.is-2
|
h2.title.is-2
|
||||||
span.mr-sm Tag:
|
span(style="margin-right: 0.5rem;") Tag:
|
||||||
span(style="font-weight: 400") {{tag}}
|
span(style="font-weight: 400") {{tag}}
|
||||||
section(v-if="posts.length > 0")
|
section(v-if="posts.length > 0")
|
||||||
PostTeaser(v-for="p in posts" :header="p" :key="p.filename")
|
PostTeaser(v-for="p in posts" :header="p" :key="p.slug")
|
||||||
b-pagination.my-lg.mx-sm(:current.sync="page" :total="count" :per-page="5"
|
b-pagination(:current.sync="page" :total="count" :per-page="5"
|
||||||
size="default" rounded)
|
size="default" rounded style="margin-top: 1rem;")
|
||||||
div(v-else)
|
div(v-else)
|
||||||
Empty
|
Empty
|
||||||
</template>
|
</template>
|
||||||
@@ -16,17 +16,16 @@ section
|
|||||||
import { Vue, Component } from 'vue-property-decorator'
|
import { Vue, Component } from 'vue-property-decorator'
|
||||||
|
|
||||||
import PostTeaser from '../components/PostTeaser.vue'
|
import PostTeaser from '../components/PostTeaser.vue'
|
||||||
import { api, normalizeArray } from '../utils'
|
import Empty from '../components/Empty.vue'
|
||||||
|
import { api } from '../utils'
|
||||||
|
|
||||||
@Component<QueryView>({
|
@Component<QueryView>({
|
||||||
components: {
|
components: {
|
||||||
PostTeaser
|
PostTeaser,
|
||||||
|
Empty
|
||||||
},
|
},
|
||||||
beforeRouteEnter (to, from, next) {
|
beforeRouteEnter ({ query, params }, from, next) {
|
||||||
console.log(to)
|
api.post('/data/posts', {
|
||||||
const { query, params } = to
|
|
||||||
|
|
||||||
api.post('/data/', {
|
|
||||||
q: query.q,
|
q: query.q,
|
||||||
cond: params.tag ? {
|
cond: params.tag ? {
|
||||||
tag: params.tag
|
tag: params.tag
|
||||||
@@ -35,7 +34,7 @@ import { api, normalizeArray } from '../utils'
|
|||||||
limit: 5,
|
limit: 5,
|
||||||
project: {
|
project: {
|
||||||
title: 1,
|
title: 1,
|
||||||
filename: 1,
|
slug: 1,
|
||||||
excerpt: 1,
|
excerpt: 1,
|
||||||
date: 1,
|
date: 1,
|
||||||
tag: 1
|
tag: 1
|
||||||
@@ -48,7 +47,7 @@ import { api, normalizeArray } from '../utils'
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
beforeRouteUpdate ({ query, params }, from, next) {
|
beforeRouteUpdate ({ query, params }, from, next) {
|
||||||
api.post('/data/', {
|
api.post('/data/posts', {
|
||||||
q: query.q,
|
q: query.q,
|
||||||
cond: params.tag ? {
|
cond: params.tag ? {
|
||||||
tag: params.tag
|
tag: params.tag
|
||||||
@@ -57,7 +56,7 @@ import { api, normalizeArray } from '../utils'
|
|||||||
limit: 5,
|
limit: 5,
|
||||||
project: {
|
project: {
|
||||||
title: 1,
|
title: 1,
|
||||||
filename: 1,
|
slug: 1,
|
||||||
excerpt: 1,
|
excerpt: 1,
|
||||||
date: 1,
|
date: 1,
|
||||||
tag: 1
|
tag: 1
|
||||||
@@ -67,6 +66,58 @@ import { api, normalizeArray } from '../utils'
|
|||||||
this.$set(this, 'count', data.count)
|
this.$set(this, 'count', data.count)
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
metaInfo () {
|
||||||
|
const { tag, page } = this.$route.params
|
||||||
|
const p0 = this.posts[0] || {}
|
||||||
|
const title = (tag ? `Tag: ${tag}` : 'Posts') + (page ? ` - Page ${page}` : '')
|
||||||
|
const description = p0.excerpt ? (() => {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.innerHTML = p0.excerpt
|
||||||
|
return div.innerText
|
||||||
|
})() : ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
meta: [
|
||||||
|
{ vmid: 'description', name: 'description', content: description },
|
||||||
|
{
|
||||||
|
hid: 'og:title',
|
||||||
|
property: 'og:title',
|
||||||
|
content: p0.title
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'og:description',
|
||||||
|
property: 'og:description',
|
||||||
|
content: description
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'og:image',
|
||||||
|
property: 'og:image',
|
||||||
|
content: p0.image
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:title',
|
||||||
|
property: 'twitter:title',
|
||||||
|
content: p0.title
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:description',
|
||||||
|
property: 'twitter:description',
|
||||||
|
content: description
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:image',
|
||||||
|
property: 'twitter:image',
|
||||||
|
content: p0.image
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hid: 'twitter:card',
|
||||||
|
property: 'twitter:card',
|
||||||
|
content: 'summary_large_image'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export default class QueryView extends Vue {
|
export default class QueryView extends Vue {
|
||||||
@@ -101,9 +152,5 @@ export default class QueryView extends Vue {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get q () {
|
|
||||||
return normalizeArray(this.$route.query.q)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
Reference in new issue
Block a user