Output source of article content: pull hook education front-end high salary training camp
What is a static site builder
- Static website generator is a tool for generating static HTML files and related resources using a series of configurations, templates and data
- This feature is also called pre rendering
- The generated website does not need a server like PHP
- You only need to run it on a Web Server or CDN that supports static resources
Benefits of static websites
- Save money, do not need a professional server, as long as you can host the space of static files
- Fast, no processing by the back-end server, only transmitting content
- Security, no back-end program execution, naturally more secure
Common static website builder
- Jekyll(Ruby)
- Hexo (Node)
- Hugo (Golang)
- Gatsby (Node/React)
- Gridsome (Node/Vue)
In addition, Next.js and Nuxt.js can also survive static websites, but they are more regarded as SSR (server-side rendering) frameworks
This kind of static website generator is also called JAMStack: an acronym combination of JavaScript, API and Markup. In essence, it is a fat front end. It realizes more functions by calling various APIs. It can also be understood as a front-end and back-end mode, but the difference is particularly obvious. Even the front-end and back-end come from multiple different manufacturers
Usage scenarios for static applications
- Not suitable for applications with a large number of routing pages: if your site has hundreds of routing pages, the pre rendering will be very slow. Of course, you only need to do it once per update, but it may take some time. Most people don't end up with thousands of static routing pages, just in case
- Not suitable for applications with a large amount of dynamic content: if the rendering route contains content specific to users viewing their content or other dynamic sources, make sure you have a placeholder component that can be displayed until the dynamic content is loaded to the client, otherwise it may be a little weird
GridSome
install
$ yarn global add @gridsome/cli or $ npm install --global @gridsome/cli
initialization
$ gridsome create my-gridsome-site
gridsome configuration
View links to official documents.
route
- gridsome will automatically generate routes according to the pages directory
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/
- Create routes programmatically
gridsome.server.js
module.exports = function (api) { api.createPages(({ createPage }) => { createPage({ path: '/my-page', component: './src/templates/MyPage.vue' }) }) }
- Dynamic routing
File based approach
src/pages/user/[id].vue becomes /user/:id.
src/pages/user/[id]/settings.vue becomes /user/:id/settings.
Based on programming mode
gridsome.server.js
module.exports = function (api) { api.createPages(({ createPage }) => { createPage({ path: '/user/:id(\\d+)', component: './src/templates/User.vue' }) }) }
- Page meta info
In vue component
<template> <div> <h1>Hello, world!</h1> </div> </template> <script> export default { metaInfo: { title: 'Hello, world!', meta: [ { name: 'author', content: 'John Doe' } ] } } </script>
- Custom 404 page
Create src/pages/404.vue component
aggregate
gridsome.server.js
const axios = require('axios') module.exports = function (api) { // Add data that needs to be pre rendered into the page 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 }) } }) }
Configure GraphQL to query data in the page
- Use in Pages and Templates
- Use in Components
<template> <Layout> <div> <h1>Posts2</h1> <ul> <li v-for="edge in $page.posts.edges" :key="edge.node.id"> <g-link :to="edge.node.path">{{ edge.node.title }}</g-link> </li> </ul> </div> </Layout> </template> <page-query> query { posts: allPost { edges { node { id title } } } } </page-query> <script>
// Query set query { allPost(sortBy: "title", order: DESC) { edges { node { title } } } } // Query a single node query { post(id: "1") { title } } // Query data in page components query { posts: allWordPressPost { edges { node { id title } } } } // Multiple queries in page components query { posts: allWordPressPost { edges { node { id title } } } books: allBooks { edges { node { id title } } } }
Query data in any component
<template> <div v-html="$static.post.content" /> </template> <static-query> query { post(id: "1") { content } } </static-query>
Functional component support
<static-query> query { post(id: "1") { content } } </static-query> <script> export default { functional: true, render(createElement, context) { const { content } = context.data.$static.post return createElement('div', { domProps: { innerHTML: content }, }) } } </script>
Set template
By default, the template for the collection name is found in src/templates/{Collection}.vue
- Create a new template Post.vue in templates
<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', metaInfo () { return { title: this.$page.post.title } } // metaInfo: { // title: '' // } } </script> <style> </style>
- Specify the template path in gridsome.config
// module.exports = { // templates: { // Post: '/blog/:year/:month/:title', // } // } module.exports = { templates: { Post: [ { path: '/posts/:id', component: './src/templates/Post.vue' } ] } }
- Modify the path of Posts2
<template> <Layout> <div> <h1>Posts2</h1> <ul> <li v-for="edge in $page.posts.edges" :key="edge.node.id"> <g-link :to="edge.node.path">{{ edge.node.title }}</g-link> </li> </ul> </div> </Layout> </template> <page-query> query { posts: allPost { edges { node { id title, path } } } } </page-query>
Use strapi to quickly develop cms and provide data support for gridsome
install
$ npx create-strapi-starter my-project gatsby-blog or $ yarn create strapi-starter my-project gatsby-blog
use
Click the content type generator to generate the corresponding set type data or single type data according to the requirements, and provide a data interface for subsequent gridsome projects. For specific usage methods, please refer to Access to official documents
Remote server installation mysql
https://www.ucloud.cn/yun/47831.html
Deploy strapi
Modify database configuration
config/database.js
module.exports = ({ env }) => ({ defaultConnection: 'default', connections: { default: { connector: 'bookshelf', settings: { client: 'mysql', host: env('DATABASE_HOST', 'localhost'), // The database host does not need to be modified if strapi and gridsome are deployed on the same server port: env.int('DATABASE_PORT', 3306), // Port number database: env('DATABASE_NAME', 'strapi'), // Database name username: env('DATABASE_USERNAME', 'strapi'), // Database user name password: env('DATABASE_PASSWORD', 'strapi'), // Database password }, options: {}, }, }, });
Developing a static site using gridsome
Execute the script described above, install gridsome and create a project
$ gridsome create my-gridsome-demo
Integrating strapi in gridsome
$ yarn add @gridsome/source-strapi or $ npm install @gridsome/source-strapi
gridsome.config.js
// This is where project configuration and plugin options are located. // Learn more: https://gridsome.org/docs/config // Changes here require a server restart. // To restart press CTRL + C in terminal and run `gridsome develop` module.exports = { siteName: 'Gridsome', plugins: [ { use: '@gridsome/source-strapi', options: { apiURL: 'http://localhost:1337', queryLimit: 1000, // Defaults to 100 contentTypes: ['post'], // Collection content to query singleTypes: ['journal'], // Single content to query // Possibility to login with a Strapi user, // when content types are not publicly available (optional). loginData: { // Protected content requires login identifier: '', password: '', }, }, }, ], }
After deploying strapi to the server, you need to configure the apiURL as the server address. It is recommended to create. env.development and. env.production to set the server address
.env.production
GRIDSOME_API_URL=server address
gridsome.config.js
module.exports = { siteName: 'Gridsome', plugins: [ { options: { apiURL: process.env.GRIDSOME_API_URL, }, }, ], }
In addition, gridsome_ API_ The URL is mixed into the Vue instance to facilitate use in the page
main.js
export default function (Vue, { router, head, isClient }) { Vue.mixin({ data() { return { GRIDSOME_API_URL: process.env.GRIDSOME_API_URL, } }, }) // Set default layout as a global component Vue.component('Layout', DefaultLayout) }
Compose page
The data in the page is obtained through GraphQL query. strapi defaults to the data in markdown format, which needs to be converted into html display using markdown it
$ yarn add markdown-it
Posts.vue
<template> <Layout> <div class="container"> <div class="journal-hero"> <h1 class="journal-header"> {{ $page.journal.desc }} </h1> </div> </div> <g-link v-for="item in $page.posts.edges" :key="item.node.id" :to="`/journal-detail/${item.node.id}`" class="journal-post"> <div class="container journal"> <h2 class="journal-title"> {{ item.node.title }} </h2> <p class="journal-excerpt"> {{ item.node.intro }} </p> </div> </g-link> <Pager class="pager" :info="$page.posts.pageInfo" nav-class="navigation" link-class="page-link page-item" activeLink-class="active" /> </Layout> </template> <page-query> query ($page: Int) { posts: allStrapiPost (perPage: 10, page: $page) @paginate { pageInfo { totalPages currentPage } edges { node { id title intro } } } journal: strapiJournal (id: 1) { desc } } </page-query> <script> import { Pager } from 'gridsome' export default { metaInfo: { title: 'journal' }, components: { Pager, }, } </script> <style> </style>
src/templates/Post.vue
<template> <Layout> <div class="journal"> <div class="container journal-container"> <div class="journal-header-detail"> <h1 class="journal-title-detail"> {{ $page.post.title }} </h1> <div class="journal-meta"> <div class="journal-author"> <span class="label"> Author </span> <span class="author-name"> {{ $page.post.admin_user.lastname }} {{ $page.post.admin_user.firstname }} </span> </div> <div class="journal-date"> <span class="label"> Date </span> <div> {{ $page.post.created_at }} </div> </div> <div class="journal-time"> <span class="label"> Time </span> <span > 1 min read </span> </div> </div> </div> <div class="journal-content" v-html="mdToHtml($page.post.content)"></div> </div> </div> </Layout> </template> <page-query> query ($id: ID!) { post: strapiPost (id: $id) { id title content admin_user { lastname firstname } created_at } } </page-query> <script> import MarkdownIt from 'markdown-it' const md = new MarkdownIt() export default { name: 'PostPage', metaInfo () { return { title: this.$page.post.title, } }, methods: { mdToHtml (markdown) { return md.render(markdown) } } } </script> <style scope> .journal:hover { background: transparent; } </style>
Deploy gridsome project to Vercel
Vercel official address
- Enter personal Center - overview - new Project - import Git Repository
- Enter the web address of the git repository as prompted
- If you have modified the scripts command and dist output directory of gridsome, you can configure them in Configure Project
- Enter git in settings, create a Deploy Hooks (for example, deploy, master branch), and then copy the created address
- Enter strapi settings Webhooks, add a new hook, paste the address just copied into the corresponding input box, check all events, and then vercel will deploy automatically as long as strapi is updated