Close
升级到 Vue 3 | Vue 2 EOL

创建 CMS 支持的博客

恭喜您刚刚发布了您的 Vue.js 网站!现在您想添加一个博客,它可以快速插入您的网站,并且您不想为了托管 WordPress 实例(或任何基于数据库的 CMS)而启动整个服务器。您只想能够添加一些 Vue.js 博客组件和一些路由,让一切正常工作,对吧?您正在寻找的是一个完全由 API 支持的博客,您可以直接从您的 Vue.js 应用程序中使用这些 API。本教程将教会您如何做到这一点,让我们深入了解!

我们将快速使用 Vue.js 构建一个 CMS 支持的博客。它使用 ButterCMS,一个以 API 为中心的 CMS,它允许您使用 ButterCMS 仪表板管理内容,并将我们的内容 API 集成到您的 Vue.js 应用程序中。您可以将 ButterCMS 用于新的或现有的 Vue.js 项目。

Butter Dashboard

安装

在您的命令行中运行此命令

npm install buttercms --save

Butter 也可以使用 CDN 加载

<script src="https://cdnjs.buttercms.com/buttercms-1.1.0.min.js"></script>

快速入门

设置您的 API 令牌

var butter = require('buttercms')('your_api_token');

使用 ES6

import Butter from 'buttercms';
const butter = Butter('your_api_token');

使用 CDN

<script src="https://cdnjs.buttercms.com/buttercms-1.1.0.min.js"></script>
<script>
var butter = Butter('your_api_token');
</script>

将此文件导入到您要使用 ButterCMS 的任何组件中。然后从控制台运行

butter.post.list({page: 1, page_size: 10}).then(function(response) {
console.log(response)
})

此 API 请求获取您的博客文章。您的帐户附带一个示例文章,您将在响应中看到它。

显示文章

为了显示文章,我们在应用程序中创建一个 /blog 路由(使用 Vue Router),从 Butter API 获取博客文章,以及一个 /blog/:slug 路由来处理单个文章。

有关其他选项(例如按类别或作者过滤),请参阅 ButterCMS API 参考。响应还包含一些我们将用于分页的元数据。

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import BlogHome from '@/components/BlogHome'
import BlogPost from '@/components/BlogPost'

Vue.use(Router)

export default new Router({
mode: 'history',
routes: [
{
path: '/blog/',
name: 'blog-home',
component: BlogHome
},
{
path: '/blog/:slug',
name: 'blog-post',
component: BlogPost
}
]
})

然后创建 components/BlogHome.vue,它将是您的博客主页,列出您最新的文章。

<script>
import { butter } from '@/buttercms'
export default {
name: 'blog-home',
data() {
return {
page_title: 'Blog',
posts: []
}
},
methods: {
getPosts() {
butter.post.list({
page: 1,
page_size: 10
}).then(res => {
this.posts = res.data.data
})
}
},
created() {
this.getPosts()
}
}
</script>

<template>
<div id="blog-home">
<h1>{{ page_title }}</h1>
     <!-- Create `v-for` and apply a `key` for Vue. Here we are using a combination of the slug and index. -->
<div
v-for="(post,index) in posts"
:key="post.slug + '_' + index"
>
<router-link :to="'/blog/' + post.slug">
<article class="media">
<figure>
<!-- Bind results using a `:` -->
<!-- Use a `v-if`/`else` if there is a `featured_image` -->
<img
v-if="post.featured_image"
:src="post.featured_image"
alt=""
>
<img
v-else
src="http://via.placeholder.com/250x250"
alt=""
>
</figure>
<h2>{{ post.title }}</h2>
<p>{{ post.summary }}</p>
</article>
</router-link>
</div>
</div>
</template>

它看起来像这样(注意我们添加了来自 https://bulma.org.cn/ 的 CSS 用于快速样式设置)

buttercms-bloglist

现在创建 components/BlogPost.vue,它将是您的博客文章页面,用于列出单个文章。

<script>
import { butter } from '@/buttercms'
export default {
name: 'blog-post',
data() {
return {
post: {}
}
},
methods: {
getPost() {
butter.post.retrieve(this.$route.params.slug)
.then(res => {
this.post = res.data
}).catch(res => {
console.log(res)
})
}
},
created() {
this.getPost()
}
}
</script>

<template>
<div id="blog-post">
<h1>{{ post.data.title }}</h1>
<h4>{{ post.data.author.first_name }} {{ post.data.author.last_name }}</h4>
<div v-html="post.data.body"></div>

<router-link
v-if="post.meta.previous_post"
:to="/blog/ + post.meta.previous_post.slug"
class="button"
>
{{ post.meta.previous_post.title }}
</router-link>
<router-link
v-if="post.meta.next_post"
:to="/blog/ + post.meta.next_post.slug"
class="button"
>
{{ post.meta.next_post.title }}
</router-link>
</div>
</template>

这是一个预览

buttercms-blogdetail

现在我们的应用程序正在拉取所有博客文章,我们可以导航到单个文章。但是,我们的下一篇文章/上一篇文章按钮不起作用。

使用带参数的路由时需要注意的一点是,当用户从 /blog/foo 导航到 /blog/bar 时,将重用相同的组件实例。由于两个路由都渲染相同的组件,因此这比销毁旧实例然后创建一个新实例更有效。

请注意,以这种方式使用组件意味着组件的生命周期钩子不会被调用。访问 Vue Router 的文档以了解有关 动态路由匹配 的更多信息

为了解决这个问题,我们需要观察 $route 对象并在路由更改时调用 getPost()

更新 <script> 部分中的 components/BlogPost.vue

<script>
import { butter } from '@/buttercms'
export default {
name: 'blog-post',
data() {
return {
post: null
}
},
methods: {
getPost() {
butter.post.retrieve(this.$route.params.slug)
.then(res => {
this.post = res.data
}).catch(res => {
console.log(res)
})
}
},
watch: {
$route: {
immediate: true,
handler(to, from) {
this.getPost()
}
}
}
}
</script>

现在您的应用程序拥有一个可以轻松地在 ButterCMS 仪表板中更新的工作博客。

类别、标签和作者

使用 Butter 的类别、标签和作者 API 来突出显示和过滤博客上的内容。

有关这些对象的更多信息,请参阅 ButterCMS API 参考

以下是如何列出所有类别并按类别获取文章的示例。在 created() 生命周期钩子上调用这些方法

methods: {
// ...
getCategories() {
butter.category.list()
.then(res => {
console.log('List of Categories:')
console.log(res.data.data)
})
},
getPostsByCategory() {
butter.category.retrieve('example-category', {
include: 'recent_posts'
})
.then(res => {
console.log('Posts with specific category:')
console.log(res)
})
}
},
created() {
// ...
this.getCategories()
this.getPostsByCategory()
}

替代模式

另一个需要考虑的模式,特别是如果您更喜欢只用 Markdown 编写,是使用类似 Nuxtent 的东西。Nuxtent 允许您在 Markdown 文件中使用 Vue 组件。这种方法类似于静态网站方法(即 Jekyll),您在 Markdown 文件中撰写博客文章。Nuxtent 在 Vue.js 和 Markdown 之间添加了很好的集成,使您能够完全沉浸在 Vue.js 世界中。

总结

就是这样!您现在拥有一个在您的应用程序中运行的完全功能的 CMS 支持的博客。我们希望本教程对您有所帮助,并使您在 Vue.js 上的开发体验更加愉快 :)