文章前言
笔记来源:拉勾教育 大前端高薪训练营
阅读建议:内容较多,建议通过左侧导航栏进行阅读
Gridsome 基础
基本介绍
Gridsome 是什么
- 一个免费、开源、基于 Vue.js 技术栈的静态网站生成器。
- 官方网站:https://gridsome.org/
- GitHub 仓库:https://github.com/gridsome/gridsome
- Gridsome 是由Vue.js驱动的Jamstack框架,用于构建默认情况下快速生成的静态生成的网站和应用。
- Gridsome是Vue提供支持的静态站点生成器,用于为任何无头CMS,本地文件或API构建可用于CDN的网站
- 使用Vue.js,webpack和Node.js等现代工具构建网站。通过npm进行热重载并访问任何软件包,并使用自动前缀在您喜欢的预处理器(如Sass或Less)中编写CSS。
- 基于 Vue.js 的 Jamstack 框架
- Gridsome 使开发人员可以轻松构建默认情况下快速生成的静态生成的网站和应用程序
- Gridsome允许在内容里面引用任何CMS或数据源。
从WordPress,Contentful或任何其他无头CMS或API中提取数据,并在组件和页面中使用GraphQL访问它。
为什么选择 Gridsome
- Vue.js for frontend - The simplest & most approachable frontend framework.
- Data sourcing - Use any Headless CMSs, APIs or Markdown-files for data.
- Local development with hot-reloading - See code changes in real-time.
- File-based page routing - Any
Name.vue
file insrc/pages
is a static route. - Dynamic routing - Any
[param].vue
file insrc/pages
is a dynamic route. - Static file generation - Deploy securely to any CDN or static web host.
- GraphQL data layer - Simpler data management with a centralized data layer.
- Automatic Code Splitting - Builds ultra performance into every page.
- Plugin ecosystem - Find a plugin for any job.
它是如何工作的
Gridsome生成静态HTML,一旦加载到浏览器中,该HTML就会渗入Vue SPA。这意味着您可以使用Gridsome构建静态网站和动态应用程序。
Gridsome为每个页面构建一个.html文件和一个.json文件。加载第一页后,它仅使用.json文件来预取和加载下一页的数据。它还为需要它的每个页面构建一个.js包(代码拆分)。
它使用vue-router进行SPA路由,并使用vue-meta来管理。
Gridsome默认添加最小57kB的gzip JS捆绑包大小(vue.js,vue-router,vue-meta和一些用于图像延迟加载的文件)。
学习条件
您应该具有有关HTML,CSS,Vue.js以及如何使用终端的基本知识。了解GraphQL的工作原理是有好处的,但不是必需的。 Gridsome是学习它的好方法。
Gridsome 需要Node.js(v8.3 +),并建议使用 Yarn。
备选方案
使用场景
- 不适合管理系统
- 简单页面展示
- 想要有更好的 SEO
- 想要有更好的渲染性能
基本使用
目标:快速了解 Gridsome 项目
-
1,安装
Gridsome CLI
# 使用 yarn yarn global add @gridsome/cli # 使用 npm npm install --global @gridsome/cli # 查看是否安装成功 gridsome --version
-
2,创建
Gridsome
项目# 创建项目 gridsome create my-gridsome-site # 进入项目中 cd my-gridsome-site # 启动开发模式,或 npm run develop gridsome develop
在创建项目时,自动安装依赖无法查看进度,如图所示:
此时,可以中断进度,然后进入项目中,手动安装依赖:
# 进入项目中 cd my-gridsome-site # 安装依赖 npm install
gridsome 项目安装依赖注意事项:
-
配置 node-gyp 编译环境
-
配置环境变量:
npm_config_sharp_libvips_binary_host
为https://npm.taobao.org/mirrors/sharp-libvips/
- https://github.com/lovell/sharp-libvips
- https://developer.aliyun.com/mirror/NPM
- https://npm.taobao.org/mirrors
- https://sharp.pixelplumbing.com/install
npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp" npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
-
配置 hosts:
199.232.68.133 raw.githubusercontent.com
-
-
3,目录结构
. ├── src │ ├── components # 公共组件 │ ├── layouts # 布局组件 │ ├── pages # 页面路由组件 │ ├── templates # 模板文件 │ ├── favicon.png # 网站图标 │ └── main.js # 应用入口 ├── static # 静态资源存储目录,该目录中的资源不做构建处理 ├── README.md ├── gridsome.config.js # 应用配置文件 ├── gridsome.server.js # 针对服务端的配置文件 ├── package-lock.json └── package.json
-
4,自己试一试
- 在
src/pages
目录中创建一个.vue
组件
- 在
-
5,构建
gridsome build
构建结果默认输出到
dist
目录中。Gridsome
会把每个路由文件构建为独立的 HTML 页面。 -
6,部署
可以把构建结果
dist
放到任何 Web 服务器中进行部署。例如,我们这里使用 Node.js 命令行工具
serve
来测试构建结果。# 安装 serve 部署静态网站 npm install -g serve # 开始部署 serve dist
部署后的结果,如图所示:
访问浏览器,查看
Network
,如图所示:或者可以部署到其它第三方托管平台:https://gridsome.org/docs/deployment/。
或是自己的服务器,都可以!
项目配置
Gridsome 需要 gridsome.config.js
才能工作。插件和项目设置位于此处。
-
gridsome.config.js
,基本配置文件如下所示:module.exports = { siteName: 'Gridsome', siteUrl: 'https://www.gridsome.org', plugins: [] }
属性 类型 默认值 说明 siteName string <dirname>
该名称通常在标题标签中使用。 siteDescription string ''
页面描述, <meta name="description" content="xxx">
pathPrefix string ''
Gridsome假定您的项目是从域的根目录提供的。如果您的项目将托管在名为my-app的子目录中,则将此选项更改为“ / my-app”。 titleTemplate string %s - <siteName>
设置标题标签的模板。 %s占位符将替换为您在页面中设置的metaInfo的标题。 plugins Array []
通过将插件添加到plugins数组来激活插件。 templates object {}
定义 collections
的路由和模板。metadata object {}
将全局元数据添加到GraphQL模式。 icon string | object './src/favicon.png'
Gridsome默认情况下会将位于src / favicon.png的任何图像用作favicon和touchicon,但您可以定义其他路径或大小等。图标应为正方形且至少16个像素。网站图标将调整为16、32、96像素。默认情况下,触摸图标的大小将调整为76、152、120、167、180像素。 configureWebpack object | Function 如果该选项是一个对象,它将与内部配置合并。 chainWebpack Function 该函数将接收由 webpack-chain
驱动的 ChainableConfig 实例。runtimeCompiler boolean false 在运行时包括Vue模板编译器。 configureServer Function 配置开发服务器。 permalinks.trailingSlash boolean true 默认情况下,在页面和模板后添加斜杠。启用此选项后,具有动态路由的页面将不包含尾部斜杠,并且服务器上必须具有额外的重写规则才能正常工作。另外,的静态路径不会自动包含尾部斜杠,而应包含在路径中: permalinks.slugify 使用自定义的Slugify方法。默认是 @sindresorhus/slugify css.split boolean false 将CSS分成多个块。默认情况下禁用拆分。拆分CSS可能会导致奇怪的行为。 css.loaderOptions Object {} 将选项传递给与CSS相关的 loader host string localhost 访问地址 port number 8080 端口号 outputDir string ‘dist’
运行gridsome构建时将在其中生成生产构建文件的目录。 插件示例:
module.exports = { plugins: [ { use: '@gridsome/source-filesystem', options: { path: 'blog/**/*.md', route: '/blog/:year/:month/:day/:slug', typeName: 'Post' } } ] }
-
注意事项:
开发过程中修改配置需要重启服务
Pages 页面
页面负责在URL上显示您的数据。每个页面将静态生成,并具有自己的带有标记的index.html文件。
在Gridsome中创建页面有两种选择:
- 单文件组件
- 使用 Pages API 以编程方式创建页面
pages 中的单文件组件
src/pages
目录中的单文件组件将自动具有其自己的URL。文件路径用于生成 URL,以下是一些基本示例:
src/pages/Index.vue
becomes/
(The frontpage)src/pages/AboutUs.vue
becomes/about-us/
src/pages/about/Vision.vue
becomes/about/vision/
src/pages/blog/Index.vue
becomes/blog/
大小自动转小写,驼峰命名会自动使用短横杠分割
src/pages 中的页面通常用于诸如 /about/ 之类的固定 URL,或用于在 /blog/ 等处列出博客文章。
使用 Pages API 创建页面
可以使用 gridsome.server.js
中的 createPages
钩子以编程方式创建页面。如果您要从外部 API 手动创建页面而不使用 GraphQL 数据层,则此功能很有用。
-
gridsome.server.js
module.exports = function (api) { api.createPages(({ createPage }) => { createPage({ path: '/my-page', component: './src/templates/MyPage.vue' }) }) }
动态路由
动态路由对于仅需要客户端路由的页面很有用。例如,根据URL中的细分从生产环境中的外部API获取信息的页面。
通过文件创建动态路由
动态页面用于客户端路由。可以通过将名称包装在方括号中来将路由参数放置在文件和目录名称中。例如:
src/pages/user/[id].vue
becomes/user/:id
.src/pages/user/[id]/settings.vue
becomes/user/:id/settings
.
注意事项:
-
在构建时,这将生成
user/_id.html
和user/_id/settings.html
,并且您必须具有重写规则以使其正常运行。 -
具有动态路由的页面的优先级低于固定路由。例如,如果您有一个
/user/create
路由和/user/:id
路由,则/user/create
路由将具有优先级。
这是一个基本的页面组件,它使用路由中的id参数来获取客户端的用户信息:
-
user/[id].vue
<template> <div v-if="user"> <h1>{{ user.name }}</h1> </div> </template> <script> export default { data() { return { user: null } }, async mounted() { const { id } = this.$route.params const response = await fetch(`https://api.example.com/user/${id}`) this.user = await response.json() } } </script>
始终使用 mounted
来获取客户端数据。由于在生成静态HTML时执行数据,因此在 created
中获取数据会引起问题。
通过编程方式创建动态路由
以编程方式创建带有动态路由的页面,以获取更高级的路径。动态参数使用 :
来指定。
每个参数都可以具有一个自定义的正则表达式,以仅匹配数字或某些值。
-
gridsome.server.js
module.exports = function (api) { api.createPages(({ createPage }) => { createPage({ path: '/user/:id(\\d+)', component: './src/templates/User.vue' }) }) }
生成重写规则
Gridsome无法为动态路由的每种可能的变体生成HTML文件,这意味着直接访问URL时最有可能显示404页。而是,Gridsome生成一个HTML文件,该文件可用于重写规则。例如,类似/ user /:id的路由将生成位于 /user/_id.html
的HTML文件。您可以具有重写规则,以将所有与 / user /:id
匹配的路径映射到该文件。
由于每种服务器类型都有自己的语法,因此必须手动生成重写规则。 afterBuild 挂钩中的 redirects 数组包含应生成的所有必要的重写规则。
-
示例代码,如下所示:
const fs = require('fs') module.exports = { afterBuild ({ redirects }) { for (const rule of redirects) { // rule.from - The dynamic path // rule.to - The HTML file path // rule.status - 200 if rewrite rule } } }
页面 meta 信息
-
Gridsome 使用 vue-meta 处理有关页面的元信息。
<template> <div> <h1>Hello, world!</h1> </div> </template> <script> export default { metaInfo: { title: 'Hello, world!', meta: [ { name: 'author', content: 'John Doe' } ] } } </script>
自定义 404 页面
创建一个 src/pages/404.vue
组件以具有一个自定义 404 页面。
Collections 集合
集合是一组节点,每个节点都包含带有自定义数据的字段。如果您要在网站上放置博客文章,标签,产品等,则集合很有用。
添加集合
集合可以通过 source plugins 添加,也可以使用 Data Store API 自己添加。
在开发和构建期间,这些集合存储在本地内存数据存储中。节点可以来自本地文件(Markdown,JSON,YAML等)或任何外部API。
使用 source plugins
添加集合
将集合添加到 Gridsome 的最简单方法是使用源插件。本示例从 WordPress 网站创建集合。源插件的 typeName 选项通常用于为插件添加的集合名称添加前缀。
-
gridsome.config.js
:module.exports = { plugins: [ { use: '@gridsome/source-wordpress', options: { baseUrl: 'YOUR_WEBSITE_URL', typeName: 'WordPress', } } ] }
你可以在这里浏览插件列表。
使用 Data Store API
添加集合
您可以从任何外部 API 手动添加集合。
本示例创建一个名为 Post 的集合,该集合从 API 获取内容并将结果作为节点添加到该集合中。
-
gridsome.server.js
const axios = require('axios') module.exports = function (api) { api.loadSource(async actions => { const collection = actions.addCollection('Post') const { data } = await axios.get('https://api.example.com/posts') for (const item of data) { collection.addNode({ id: item.id, title: item.title, content: item.content }) } }) }
了解有关 Data Store API 的更多信息。
GraphQL数据层
GraphQL数据层是在开发模式下可用的工具。这是临时存储到 Gridsome
项目中的所有数据的地方。可以将其视为可帮助您更快更好地处理数据的本地数据库。
来自 GraphQL 数据层的数据将生成为静态内容。
数据层和导入数据的源之间没有实时连接。这意味着您需要重新生成网站以获取最新的数据更新。
如果需要动态数据,则应使用客户端数据。
提示:默认情况下,Pages 也 Site metadata 已添加到数据层。
GraphQL 中的集合
-
开发环境,启动服务,暴露出数据层地址,只有开发环境可访问,如图所示:
每个集合将向 GraphQL schema 添加两个根字段,这些根字段用于检索页面中的节点。
字段名称是根据集合名称自动生成的。如果您将集合命名为 Post,那么在架构中将具有以下可用字段:
post
通过ID
获取单个节点。allPost
获取节点列表(可以排序和过滤等)。
自动生成 schema
处理数据
- How to import data.
- How to query data.
- How to filter data.
- How to create taxonomy pages.
- How to paginate data.
- How to add client-side / dynamic data.
在 GraphQL
中查询数据
-
查询语句,示例如下:
# 通过 ID 获取单个节点 # query { # post(id: 2) { # id # title # content # } # } # 获取节点列表 query { allPost { edges { node { id title } } } }
-
查询结果,如图所示:
在页面中查询 GraphQL
将数据从GraphQL
数据层查询到任何页面,模板或组件中。在Vue组件中,使用 <page-query>
或 <static-query>
块添加查询。
-
在 Pages 和 Templates 中使用
<page-query>
-
在 Components 中使用 ```
-
pages/posts.vue
<template> <Layout> <div> <h1>Posts2</h1> <ul> <li v-for="edge in $page.posts.edges" :key="edge.node.id"> <!-- 类似 router-link --> <g-link to="/">{{ edge.node.title }}</g-link> </li> </ul> </div> </Layout> </template> <page-query> query { posts: allPost { edges { node { id title } } } } </page-query>
此数据是通过 预渲染 静态化 出来的。
分析总结
**使用 GraphQL,您仅查询所需的数据。**这使得处理数据更加容易和整洁。
- 查询总是从
query
开始 - 然后是
Posts
(可以是任何东西) - 然后写一些内容例如
posts: allWordPressPost
。 allWordPressPost
是您要查询的GraphQL集合的名称。posts:
部分是可选的别名。- 使用
posts
作为别名时,您的数据将位于$page.posts
(如果使用<static-query>
,则为$static.posts
)。否则,它将在$page.allWordPressPost
上可用。
探索可用的类型和字段
您可以通过在 GraphQL 资源管理器中打开架构选项卡来浏览可用字段。
阅读有关如何在 GraphQL 中查询节点的更多信息:https://gridsome.org/docs/querying-data/。
Templates
模板用于为集合中的节点创建单个页面。节点需要相应的页面才能显示在其自己的URL上。
设置模板
-
在
src/templates
目录下,创建Post.vue
模板<template> <Layout> <div> <h1>Post Page</h1> </div> </Layout> </template> <script> export default { name: "PostPage", }; </script> <style> </style>
-
在
gridsome.config.js
中,配置模板选项module.exports = { siteName: '拉勾教育', siteDescription: '大前端', plugins: [], templates: { // 配置模板 Post: [ { // id 表示数据中存在的真实有效的字段 path: '/posts/:id', component: './src/templates/Post.vue' } ] } }
将数据添加到模板
-
src/templates/Post.vue
,使用<page-query>
添加查询,将数据设为动态的<template> <Layout> <div> <h1>{{ $page.post.title }}</h1> <div>{{ $page.post.content }}</div> </div> </Layout> </template> <page-query> query ($id: ID!) { post(id: $id) { id title content } } </page-query> <script> export default { name: "PostPage", }; </script>
注意:
query ($id: ID!) {} :
- id :指的是在
gridsome.config.js
中配置模板时填写的动态路由:id
; - ID! :是指 对应字段 ID,并且是非空的
- id :指的是在
节点字段作为 meta info
-
在
src/templates/Post.vue
中,配置metainfo
<script> export default { name: "PostPage", // 无法访问 page-query // metaInfo: { // title: // } metaInfo () { return { title: this.$page.post.title } } }; </script>