使用gridsome和strapi搭建静态站点

文章内容输出来源:拉勾教育前端高薪训练营

什么是静态网站生成器

  • 静态网站生成器是使用一系列配置、模板以及数据,生成静态HTML文件及相关资源的工具
  • 这个功能也叫预渲染
  • 生成的网站不需要类似PHP这样的服务器
  • 只需要放在支持静态资源的Web Server或CDN上即可运行

静态网站的好处

  • 省钱,不需要专业的服务器,只要能托管静态文件的空间即可
  • 快速,不经过后端服务器的处理,只传输内容
  • 安全,没有后端程序执行,自然会更安全

常见的静态网站生成器

  • Jekyll(Ruby)
  • Hexo (Node)
  • Hugo (Golang)
  • Gatsby (Node/React)
  • Gridsome (Node/Vue)
    另外,Next.js和Nuxt.js也能生存静态网站,但是它们更多被认为是SSR(服务端渲染)框架

这类静态网站生成器还有个名字叫JAMStack:JavaScript、API和Markup的首字母组合,其本质上是一种胖前端,通过调用各种API来实现更多的功能,也可以理解为是一种前后端模式,只不过分得特别明显,甚至前后端来自多个不同的厂商

静态应用的使用场景

  • 不适合有大量路由页面的应用:如果您的站点有成百上千条路有页面,则预渲染将非常缓慢。当然,您每次更新只需要做一次,但是可能要花一些时间。大多数人不会最终获得数千条静态路由页面,而只是以防万一
  • 不适合有大量动态内容的应用:如果渲染路线中包含特定于用户查看其内容或其他动态源的内容,则应确保您具有可以显示的占位符组件,知道动态内容加载到客户端为止,否则可能有点怪异

GridSome

安装

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

初始化

$ gridsome create my-gridsome-site

gridsome配置

查看官方文档链接.

路由

  • gridsome会根据pages牡目录自动生成路由

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/

  • 编程方式创建路由
    gridsome.server.js
module.exports = function (api) {
  api.createPages(({ createPage }) => {
    createPage({
      path: '/my-page',
      component: './src/templates/MyPage.vue'
    })
  })
}
  • 动态路由
    基于文件的方式

src/pages/user/[id].vue becomes /user/:id.
src/pages/user/[id]/settings.vue becomes /user/:id/settings.

基于编程方式
gridsome.server.js

module.exports = function (api) {
  api.createPages(({ createPage }) => {
    createPage({
      path: '/user/:id(\\d+)',
      component: './src/templates/User.vue'
    })
  })
}
  • Page meta info
    在vue组件中
<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组件

集合
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
      })
    }
  })
}

配置GraphQL,在页面中查询数据

  • 在Pages和Templates使用
  • 在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 {
  allPost(sortBy: "title", order: DESC) {
    edges {
      node {
        title
      }
    }
  }
}

// 查询单个节点
query {
  post(id: "1") {
    title
  }
}

// 查询页面组件中的数据
query {
  posts: allWordPressPost {
    edges {
      node {
        id
        title
      }
    }
  }
}

// 页面组件中的多个查询
query {
  posts: allWordPressPost {
    edges {
      node {
        id
        title
      }
    }
  }
  books: allBooks {
    edges {
      node {
        id
        title
      }
    }
  }
}

查询任意组件中的数据

<template>
  <div v-html="$static.post.content" />
</template>

<static-query>
query {
  post(id: "1") {
    content
  }
}
</static-query>

功能组件支持

<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>

设置模板
默认情况下会在src/templates/{Collection}.vue查找集合名称的模板

  • 在templates中新建模板Post.vue
<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>
  • 在gridsome.config中指定模板路径
// module.exports = {
//   templates: {
//     Post: '/blog/:year/:month/:title',
//   }
// }
module.exports = {
  templates: {
    Post: [
      {
        path: '/posts/:id',
        component: './src/templates/Post.vue'
      }
    ]
  }
}
  • 修改Posts2的path
<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>

使用strapi快速开发cms,为gridsome做数据支持

安装

$ npx create-strapi-starter my-project gatsby-blog
or
$ yarn create strapi-starter my-project gatsby-blog 

使用
点击《内容类型生成器》,可以根据需求生生成对应的集合类型数据或者单一类型数据,为之后的gridsome项目提供数据接口,具体的使用方法请查阅官方文档

远程服务器安装mysql
https://www.ucloud.cn/yun/47831.html

部署strapi
修改数据库配置
config/database.js

module.exports = ({ env }) => ({
  defaultConnection: 'default',
  connections: {
    default: {
      connector: 'bookshelf',
      settings: {
        client: 'mysql',
        host: env('DATABASE_HOST', 'localhost'), // 数据库主机,如果strapi和gridsome部署在同一服务器则不用修改
        port: env.int('DATABASE_PORT', 3306), // 端口号
        database: env('DATABASE_NAME', 'strapi'), // 数据库名称
        username: env('DATABASE_USERNAME', 'strapi'), // 数据库用户名
        password: env('DATABASE_PASSWORD', 'strapi'), // 数据库密码
      },
      options: {},
    },
  },
});

使用gridsome开发一个静态站点

执行上文介绍的脚本,安装gridsome并创建一个工程

$ gridsome create my-gridsome-demo

在gridsome中集成strapi

$ 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'], // 需要查询的集合内容
        singleTypes: ['journal'], // 需要查询的单个内容
        // Possibility to login with a Strapi user,
        // when content types are not publicly available (optional).
        loginData: { // 受保护的内容需要登录
          identifier: '',
          password: '',
        },
      },
    },
  ],
}

将strapi部署到服务器后,需要将apiURL配置成服务器地址,这里推荐新建.env.development和.env.production来设置服务器地址
.env.production

GRIDSOME_API_URL=服务器地址

gridsome.config.js

module.exports = {
  siteName: 'Gridsome',
  plugins: [
    {
      options: {
        apiURL: process.env.GRIDSOME_API_URL,
      },
    },
  ],
}

另外将GRIDSOME_API_URL混入Vue实例中,方便页面中使用
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)
}

编写页面
页面中的数据都是通过GraphQL查询得来,strapi默认是markdown格式的数据,需要利用markdown-it转换成html展示

$ 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>

将gridsome项目部署到Vercel
Vercel官方地址

  1. 进入个人中心 - overview - new Project - import Git Repository
  2. 根据提示输入git仓库的网页地址
  3. 如果修改过gridsome的scripts命令和dist输出目录等,可在Configure Project中配置
  4. 进入settings中的git,创建一个Deploy Hooks(例如deploy,master分支),然后复制创建好的地址
  5. 进入strapi-设置-Webhooks,添加一个新的hook,将刚刚复制的地址粘贴到对应的输入框,勾选上所有事件,之后只要strapi有更新,vercel就会自动部署
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要使用Nuxt.js搭建一个静态站点,可以按照以下步骤进行: 1. 创建一个新的Nuxt.js项目。可以使用npx create-nuxt-app命令来创建一个基本的Nuxt.js项目。 2. 在Nuxt.js项目中创建页面。在pages目录下创建Vue.js文件,每个文件将对应站点中的一个页面。 3. 配置Nuxt.js生成静态站点。在nuxt.config.js文件中配置generate选项,指定需要生成的静态站点的路由和其他选项。 4. 运行npm run generate命令来生成静态站点。这将在dist目录下生成静态站点的文件。 5. 将生成的静态站点上传到Web服务器或静态站点托管服务中,即可将站点部署到互联网上。 以上是使用Nuxt.js搭建静态站点的基本步骤,可以根据需要进行更多的配置和定制。 ### 回答2: Nuxt.js是一个基于Vue.js的开源框架,可以帮助我们快速搭建起一个静态站点。 首先,我们需要安装Nuxt.js。可以通过npm工具在命令行中运行以下命令来进行安装: ``` npm install -g create-nuxt-app ``` 安装完成后,我们可以使用create-nuxt-app命令来创建一个新的Nuxt.js项目: ``` create-nuxt-app my-static-site ``` 运行上述命令后,系统会提示我们选择Nuxt.js的一些配置选项,例如应用名称、项目描述、UI框架等等。选择完毕后,系统会自动帮我们创建好项目的文件结构。 接下来,我们需要在项目中创建一些静态页面。在Nuxt.js中,我们可以在`pages/`目录下创建.vue文件,每个.vue文件对应一个我们想要生成的静态页面。 例如,我们在`pages/`目录下创建一个名为`index.vue`的文件,内容如下: ```vue <template> <div> <h1>Welcome to my static site</h1> <p>This is the homepage of my static site. Enjoy!</p> </div> </template> ``` 通过这样的方式,我们可以在`pages/`目录下创建多个.vue文件,并编写对应的HTML代码来构建我们所需的静态页面。 最后,我们需要通过命令行运行以下命令来生成静态站点: ``` npm run generate ``` 运行上述命令后,系统会根据我们在`pages/`目录下创建的.vue文件生成对应的HTML文件,并将这些HTML文件保存在项目的`dist/`目录下。 至此,我们就通过Nuxt.js成功搭建了一个静态站点。我们可以将`dist/`目录下生成的HTML文件上传到服务器上,通过访问对应的URL来浏览我们搭建静态站点。 ### 回答3: Nuxt.js 是一个基于 Vue.js 的通用应用框架,它可以帮助我们快速、高效地搭建静态站点。 首先,在电脑上安装好 Node.js 环境。然后,我们可以使用 npm 或者 yarn 安装 Nuxt.js,命令如下: ``` npm install -g create-nuxt-app # 或者 yarn global add create-nuxt-app ``` 安装完成后,我们可以使用 create-nuxt-app 命令创建一个新的 Nuxt.js 项目,命令如下: ``` create-nuxt-app my-static-site ``` 接下来,根据命令行的提示进行配置选择。一般来说,我们选择静态站点的模板和一些其他配置选项,然后等待创建完成。 创建完成后,进入到新创建的项目目录,运行以下命令启动 Nuxt.js 服务器: ``` npm run dev # 或者 yarn dev ``` 此时,我们可以在浏览器中访问 http://localhost:3000 查看项目运行情况。同时,我们可以在项目目录中的 `pages` 文件夹下创建和编辑页面,Nuxt.js 会自动根据页面的目录结构生成路由和对应的静态页面。 接着,我们可以继续编辑页面,包括添加样式、处理数据请求等。同时,我们可以使用 Nuxt.js 提供的插件系统来增强项目的功能。 最后,当我们完成了所有的页面编写和功能开发后,可以使用以下命令生成静态站点的文件: ``` npm run generate # 或者 yarn generate ``` 生成的静态站点文件会存放在项目目录的 `dist` 文件夹中,我们可以将这些文件部署到任何支持静态文件访问的服务器上。 总之,Nuxt.js 提供了便捷的方式来搭建静态站点。我们只需要使用一些简单的命令和编辑页面代码,就能快速地创建和部署一个功能完善的静态站点

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值