基于Gridsome建立一个基于Vue.JS和Markdown的博客


本文介绍如何使用Gridsome的JAMstack生成静态站点,在文章的最后,我们将使用Markdown构建一个博客作为生成的内容,使用GraphQL来查询将在页面上显示的帖子。

静态站点生成器是Web开发的新混合方法的一部分,允许您在计算机上本地构建功能强大的网站,但是将站点预构建为静态文件以进行部署。JAMstack是一种构建网站和应用程序的新方法,可提供更好的性能,更高的安全性,更低的扩展成本和更好的开发人员体验

介绍Gridsome
Gridsome是一个Vue.js驱动的静态站点生成器,用于创建可在任何地方部署的快速安全的网站。它使开发人员可以轻松构建现代JAMstack网站。
Gridsome捆绑了一些难以错过的功能,这使它成为最受欢迎的静态站点生成器之一。其中一些功能包括:

  • 使用热重新加载进行本地开发 - 在开发过程中实时查看更改。
  • 编写Vue.js代码 - 一个轻量级且易于使用的前端框架。
  • GraphQL数据层 - 为您的所有数据集中管理数据。
  • 自动页面路由 - 使用文件快速创建和管理页面。
  • 渐进式图像支持 - 自动调整大小,优化和延迟加载图像。
  • 自动页面预取 - 页面在后台加载以便快速浏览。
  • 自动优化的代码 - 开箱即用的代码分割和资产优化。
  • 快速静态页面生成 - 安全,快速地部署到任何静态Web主机。
  • 数据源插件 - 从流行的无头CMS,API或Markdown文件添加数据。

建立一个Gridsome项目
我们需要设置一个新的Gridsome项目,为此我们将需要运行以下命令。
第一步,使用npm或yarn在计算机上安装Gridsome CLI。

$ npm install --global @gridsome/cli or
$ yarn global add @gridsome/cli

安装CLI后的下一步是继续创建一个名为的新项目Telerik-blog并运行该项目。

// create a new gridsome project
$ gridsome create telerik-blog
$ cd telerik-blog
$ gridsome develop

运行这些命令后,本地开发服务器应该运行在http://localhost:8080,访问可显示的示例页面。

如果我们尝试更改此布局页面上的任何内容,那么我们将看到它会自动更改屏幕上的内容。这是我们之前谈到的Gridsome Hot Reloading功能的结果。

用Gridsome构建一个博客
我们将开始描述我们试图通过博客实现的目标 - 我们将有一个包含帖子列表的单个页面,并且每个帖子都包含Markdown中的内容。为了实现这一目标,我们需要安装一个Gridsome插件叫做gridsome/source-filesystem有助于转换文件转换成可以与GraphQL在你的组件中获取内容。继续使用此命令安装程序包:

yarn add @gridsome/source-filesystem or 
npm install @gridsom/source-filesystem

并在gridsome.config.js文件中配置它:

module.exports = {
  siteName: 'Gridsome Blog',
  siteDescription: 'A simple blog designed with Gridsome',
  plugins: [
    {
      use: '@gridsome/source-filesystem',
      options: {
        path: 'content/posts/**/*.md',
        typeName: 'Post',
        route: '/blog/:slug'
      }
    }
  ]
}

上面的配置是我们设置source-filesystem插件所需的。这里设置的选项:

  • path:我们将在帖子中消费的降价内容的位置。
  • typeName:GraphQL类型和模板名称。一个.vue文件src/templates必须符合typeName有它的模板。
  • route:这是每个帖子将遵循的路线,即 localhost:8080/blog/new-post

Gridsome使用Layouts作为页面和模板的包装器。布局包含页眉,页脚或侧边栏等slot组件以及插入来自页面和模板的内容的组件。

<template>
  <div class="layout">
    <slot/> <!-- Page/Template will be inserted here -->
    <div class=
"footer">
      <p>
        Built with
        <a class=
"link" href="//gridsome.org">Gridsome</a>
        & Made with  by
        <a class=
"link" href="//twitter.com/lauragift21">Gift Egwuenu</a>
      </p>
    </div>
  </div>
</template>

上面的代码块是我们的Default.vue组件。我们可以继续浏览GitHub Repo中使用的样式。

创建页面布局
页面布局将列出所有博客帖子,也将作为主页。在Gridsome中,Pages用于普通页面以及列表和分页GraphQL集合。在这种情况下,我们的博客文章是集合。
页面URL是根据文件的位置和名称生成的。例如,如果我们在pages目录中创建一个文件并命名它Index.vue,它将被视为index.html主页。如果我们创建一个文件并调用它About.vue也同样适用- 它将被视为about.html并将被链接为/about。
这就是路由在Pages中的工作方式。因为我们只想在一个页面中显示所有内容,所以我们可以继续创建Index.vue 文件,或者如果我们已经为我们生成了一个文件,那么我们可以使用它。
我们Index.vue应该看起来像这样:

<template>
  <Layout>
    <header class="header">
      <h1>Gridsome Blog</h1>
      <p>A simple blog designed with Gridsome</p>
    </header>
  </Layout>
</template>

现在我们有了主页,我们可以继续创建一个博客帖子列表并在页面上显示。我们可以在组件目录中创建一个PostList.vue文件,我们将在其中创建用于显示博客帖子列表:

<template>
  <div class="post-list">
    <hr class=
"line" />
    <p class=
"date" v-html="post.date" />
    <h1 class=
"title" v-html="post.title" />
    <p class=
"description" v-html="post.description" />
    <b> {{post.timeToRead}} min read </b>  &nbsp
    <g-link :to=
"post.path" class="read">Read More...</g-link>
  </div>
</template>

<script>
export default {
  props: [
"post"],
};
</script>

在此文件中,我们有用于显示帖子列表的内容,我们还添加了一个post属性,使我们能够将数据从父组件传递到PostList子组件。
返回Index.vuePages目录中,请记住我之前提到的Gridsome为您的所有数据提供了集中数据管理,在我们的例子中是指GraphQL。它使用<page-query>并将<static-query>数据提取到页面,模板和组件中。在这里,我们需要提取我们在Markdown中编写的内容目录中的所有帖子,并将它们显示在我们的Vue组件中。

<page-query>
query {
  allPost {
    totalCount
    edges {
      node {
        id
        title
        timeToRead
        description
        date (format: "D MMMM YYYY")
        path
      }
    }
  }
}
</page-query>

现在,我们的Vue组件中有内容了,我们可以将它们传递给PostList.vue组件,如下所示:

<section class="posts">
  <PostList v-for=
"edge in $page.allPost.edges" :key="edge.node.id" :post="edge.node" />
</section>

显示帖子布局
现在我们有一个content显示文件夹中的帖子列表。下一步是在单击其中一个帖子时显示单个帖子。我们将使用模板来处理这个问题。在Gridsome中,Template用于显示GraphQL集合的单个帖子视图。添加以下内容到templates目录中Post.vue文件。

<template>
  <Layout>
    <br>
    <g-link to="/" class="link">  &larr; Go Back</g-link>
    <div class=
"post-title">
      <h1>{{$page.post.title}}</h1>
        <p class=
"post-date"> {{ $page.post.date}} | {{$page.post.timeToRead}} min read 
      </p>
    </div>
    <div class=
"post-content">
      <p v-html=
"$page.post.content" />
    </div>
  </Layout>
</template>

要查询单个帖子的内容,我们将使用page-query:

<page-query>
query Post ($path: String!) {
   post: post (path: $path) {
    id
    title
    content
    date (format: "D MMMM YYYY")
    timeToRead
  }
}
</page-query>

完成后,当您单击read more主页时,您应该看到我们在gridsome.config.js中配置的带有帖子标题的单个帖子的内容