本文介绍如何使用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>   <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"> ← 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中配置的带有帖子标题的单个帖子的内容