内容输出来源拉勾教育大前端高薪训练营
一、Gridsome
什么是静态网站生成器
- 静态网站生成器是使用一系列配置、模版以及数据、生成静态HTMl文件及相关工具
- 同时这个功能也叫预渲染
- 生成的网站不需要类似
PHP
这样的服务器 - 只需要放到静态资源的
Web Server
或者CDN
上运行
静态网站的好处
- 省钱 不需要专业的服务器,只要能托管静态文件的空间即可
- 快速 不经过后端服务器的出来,只传输内容
- 安全 没有后端程序的执行,自然会更安全
常见的静态网站生成器
- Jekyll (Ruby)
- Hexo (Node)
- Hugo (Golang)
- Gatsby (Node/React)
- Gridsome (Node/Vue)
- 另外,Next.js, Nuxt.js 也能生成静态网站,但是他们更多认为是SSR(服务端渲染)框架
JAMStack
- 这类静态网站生成器还有个漂亮的名字叫JAMStack
- JAMStack的JAM是JavaScript、API和Markup的首字母组合本质上是一种胖前端,通过调用各种API来实现更多的功能
- 其实也是一种前后端的模式,只不过离得比较开,甚至前后端来自多个不同的厂商
静态应用的使用场景
- 不适合有大量路由页面的应用
- 如果您的站点有成百上千条路由页面,则预渲染将非常缓慢。当然,您每次更新只需要做一次,但是可能要花一些时间。大多数人不会最终获得数千条静态路由页面,而只是以防万一
- 不适合有大量动态内容的应用
- 如果渲染路线中包含特定于用户查看其内容或其他动态源的内容,则应确保您具有可以显示的占位符组件,直到动态内容加载到客户端为止。否则可能有点怪异
二、初始化Gridsome 项目
因为 Gridsome
依赖了一个特殊的模块 sharp
, sharp
又依赖了一个 libvips
, 因为国内网络环境原因,所以我们很难去下载这个两个依赖
sharp
解决
// 设置淘宝镜像
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"
npm install sharp
除此之外我们还需要安装 node-gyp
npm install -g node-gyp
还需 Python
环境, Mac 环境下是自带 Python
的
安装 Gridsome 脚手架
yarn global add @gridsome/cli
npm install --global @gridsome/cli
gridsome create my-gridsome-site // 初始化项目
cd my-gridsome-site
gridsome develop
安装依赖的时候比较慢,又没有进度条,可以按ctrl+C
中断掉,然后进入已经生成的my-gridsome-site
目录下,执行rm -rf node_modules
删除半成品 node_modules
,然后重新执行 `npm install ,此时就能看到进度了。
安装好依赖之后,可以在package.json
里查看命令。
执行npm run develop
启动项目
三、预渲染
GridSome 默认一个组件对应了一个路由也就是 about
和 index
分别对应不同的路由,
四、Gridsome-目录结构
// main.js
// This is the main.js file. Import global CSS and scripts here.
// The Client API can be used here. Learn more: gridsome.org/docs/client-api
import DefaultLayout from '~/layouts/Default.vue'
export default function (Vue, { router, head, isClient }) {
// Set default layout as a global component
Vue.component('Layout', DefaultLayout)
}
gridsome.config.js
gridsome
的配置文件gridsome.server.js
也是girdsome
的配置文件,是配置服务端的,Gridsome
内部的服务配置。Default.vue
中有个特别之处,query
就是专门查询gridsome数据给组件使用components
放一些公共组件static
静态资源dist
打包文件
<static-query>
query {
metadata {
siteName
}
}
</static-query>
五、Gridsome-项目配置
module.exports = {
siteName: '拉钩教育', // 页面上的名称
pathPrefix: '/my-app', // 路径前缀, 部署是否有子目录
templates: {}, // 定义路由模版
configgureWebapck: {}, // type Object | Function webpack 配置
siteDescription: '大前端', // meta 名称
plugins: [] // 配置插件
}
注意: 修改的配置文件必须重启
六、Gridsome-Pages
pages 就是我们项目当中的路由组件,最终会生成路由页面,在编译的时候会成为静态的HTML
两种创建方式
- 基于文件创建 直接新建文件 例如
foo.vue
- 基于API,也就是通过变成创建
// gridsome.server.js 配置
api.createPages(({ createPage }) => {
// Use the Pages API here: https://gridsome.org/docs/pages-api/
createPage({
path: '/my-page',
component: './src/templates/MyPage.vue'
})
})
重启服务就可以看到创建的页面组件了
动态路由
1、pages
下面创建的页面文件名称用方括号括起来,作为动态路由参数
src/pages/user/[id].vue
<template>
<div>
<h1>
User {{ $route.params.id }} Page
</h1>
</div>
</template>
<script>
export default {
name: 'UserPage'
}
</script>
<style>
</style>
重启之后可以拿到页面传过来的参数了~
API 创建
api.createPages(({ createPage }) => {
createPage({
path: '/user/:id(\\d+)',
component: './src/templates/User.vue'
})
})
七、Gridsome-添加集合
创建一个post1 组件
<template>
<Layout>
<h1>Posts1</h1>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</Layout>
</template>
<script>
import axios from 'axios'
export default {
name: 'Posts1',
data () {
return {
posts: []
}
},
async created () {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
this.posts = data
}
}
</script>
<style>
</style>
通过这种方式渲染不是静态化渲染的,它是在客户端动态加载的,我们需要用预渲染方式将数据渲染到页面中
预渲染数据
// gridsome.server.js
const axios = require('axios')
module.exports = function (api) {
api.loadSource(async ({ addCollection }) => {
const collection = addCollection('Post')
const { data } = await axios.get('https://jsonplaceholdes.typicode.com/posts')
for (const item of data) {
collection.addNode({
id: item.id,
title: item.title,
content: item.body
})
}
})
}
重启启动,下一步获取数据
八、在GraphQl中查询数据
访问 http://localhost:8080/___explore
query {
post (id : 2) {
id
title
content
}
}
九、在页面中查询GraphQl
组件中使用 <static-query></static-query>
页面路由中使用 <page-query></page-query>
<template>
<Layout>
<h1>Posts2</h1>
<ul>
<li v-for="edge in $page.posts.edges" :key="edge.node.id">
<g-link to="/">{{edge.node.title}}</g-link>
</li>
</ul>
</Layout>
</template>
<script>
export default {
name: 'Posts2',
}
</script>
<style>
</style>
<page-query>
query {
posts: allPost {
edges {
node {
id
title
}
}
}
}
</page-query>
十、使用模版渲染节点页面
Templates for collections
配置路由模版
// gridsome.config.js
module.exports = {
siteName: '拉钩教育',
siteDescription: '大前端',
plugins: [],
templates: {
Post: [
{
path: '/posts/:id',
component: './src/templates/Post.vue'
}
]
}
}
创建一个Post.vue 预渲染页面,从GraphQL获取的数据
<template>
<Layout>
<h1>{{$page.post.title}}</h1>
<p>{{$page.post.content}}</p>
</Layout>
</template>
<page-query>
// ID! 不能为空,动态路由参数会自动传入进来
query($id: ID!) {
post(id: $id) {
id
title
content
}
}
</page-query>
<script>
export default {
name: 'PostPage',
metaInfo () {
return {
title: this.$page.post.title
}
}
}
</script>
<style>
</style>
那么到这里,Gridsome 基础我们就总结完了,后续我会分享一个Gridsome 的案例。