[技术翻译]使用Nuxt生成静态网站

本周再来翻译一些技术文章,本次预计翻译三篇文章以下:javascript

我翻译的技术文章都放在一个github仓库中,若是以为有用请点击star收藏。我为何要建立这个git仓库?目的是经过翻译国外的web相关的技术文章来学习和跟进web发展的新思想和新技术。git仓库地址:https://github.com/yzsunlei/javascript-article-translatejava

静态网站现在再次流行起来了。信息站和品牌宣传站再也不须要使用WordPress之类的内容管理系统来动态更新。node

使用静态网站生成器,您能够从无源CMS,API等动态源以及Markdown文件等文件中获取内容。jquery

Nuxt是基于Vue.js的出色的静态网站生成器,可轻松用于构建静态网站。使用Nuxt,从动态内容构建静态网站所须要作的就是建立模板,以从API和Markdown文件等动态源动态显示内容。而后,在Nuxt配置文件中,咱们静态定义路由,以便它能够经过相同的路由将内容生成为静态文件。webpack

在本文中,咱们将使用Nuxt构建新闻网站,并将使用https://newsapi.org/的News API 做为内容。您必须先了解Vue.js,而后才能使用Nuxt创建网站,由于Nuxt是基于Vue.js的框架。ios

首先,咱们在News API网站上注册API密钥。若是咱们只想获取头条新闻,它是免费的。咱们开始来使用Nuxt CLI构建网站。咱们经过键入如下命令来运行:git

npx create-nuxt-app news-website

这将在news-website文件夹中建立初始项目文件。运行该向导时,咱们不为服务器端框架选择任何内容,不为UI框架选择任何内容,不为测试框架选择任何内容,不为Nuxt模式选择通用文件,最后根据您的状况选择是否包含Axios请求库,使用lint进行代码整理和prettify进行代码美化。

接下来,咱们须要安装一些软件包。咱们须要@nuxtjs/dotenv用于在本地读取环境变量的程序包和country-list用于在咱们的网站上获取国家列表的库。要安装它们,咱们运行:

npm i @nuxtjs/dotenv country-list

如今咱们能够开始创建咱们的网站了。在default.vue文件中,咱们将现有代码替换为:

<template>  
  <div>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <nuxt-link class="navbar-brand" to="/">News Website</nuxt-link>
      <button
        class="navbar-toggler"
        type="button"
        data-toggle="collapse"
        data-target="#navbarSupportedContent"
        aria-controls="navbarSupportedContent"
        aria-expanded="false"
        aria-label="Toggle navigation"
      >
        <span class="navbar-toggler-icon"></span>
      </button> <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item active">
            <nuxt-link class="nav-link" to="/">Home</nuxt-link>
          </li>
          <li class="nav-item dropdown">
            <a
              class="nav-link dropdown-toggle"
              href="#"
              id="navbarDropdown"
              role="button"
              data-toggle="dropdown"
              aria-haspopup="true"
              aria-expanded="false"
            >Headliny by Country</a>
            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
              <nuxt-link
                class="dropdown-item"
                :to="`/headlines/${c.code}`"
                v-for="(c, i) of countries"
                :key="i"
              >{{c.name}}</nuxt-link>
            </div>
          </li>
        </ul>
      </div>
    </nav>
    <nuxt />
  </div>
</template>

<script>
import { requestsMixin } from "~/mixins/requestsMixin";
const { getData } = require("country-list");

export default {
  mixins: [requestsMixin],
  data() {
    return {
      countries: getData()
    };
  }
};
</script>

<style>
.bg-light {
  background-color: lightcoral !important;
}
</style>

这是用于定义咱们网站布局的文件。咱们在此处添加了Bootstrap导航栏。该栏包含主页连接和国家列表的下拉列表。这些nuxt-link组件都是指向页面的连接,这些页面用于在生成静态文件时获取国家/地区的标题。能够经过调用函数从该部分的country-list包中获取国家。在本节中,咱们经过覆盖类的默认颜色来更改导航栏的背景颜色。本部分底部的组件将显示咱们的内容。

scriptgetDatastyle.bg-lightnuxttemplate

接下来,咱们建立一个mixins文件夹并建立一个名为requestsMixin.jsfile的文件。在其中,咱们添加:

const APIURL = "https://newsapi.org/v2";  
const axios = require("axios");
export const requestsMixin = {  
  methods: {  
    getHeadlines(country) {  
      return axios.get(  
        `${APIURL}/top-headlines?country=${country}&apiKey=${process.env.VUE_APP_APIKEY}`  
      );  
    }, getEverything(keyword) {  
      return axios.get(  
        `${APIURL}/everything?q=${keyword}&apiKey=${process.env.VUE_APP_APIKEY}`  
      );  
    }  
  }  
};

该文件包含用于从News API获取按国家/地区和关键字做为标题的代码。

而后,在pages文件夹中,咱们建立headlines文件夹,而后在文件headlines夹中,建立_countryCode.vue文件。在文件中,咱们添加:

<template>  
  <div class="container">  
    <h1 class="text-center">Headlines in {{getCountryName()}}</h1>  
    <div v-if="headlines.length > 0">  
      <div class="card" v-for="(h, i) of headlines" :key="i">  
        <div class="card-body">  
          <h5 class="card-title">{{h.title}}</h5>  
          <p class="card-text">{{h.content}}</p>  
          <button class="btn btn-primary" :href="h.url" target="_blank" variant="primary">Read</button>  
        </div>  
        <img :src="h.urlToImage" class="card-img-bottom" />  
      </div>  
    </div>  
    <div v-else>  
      <h2 class="text-center">No headlines found.</h2>  
    </div>  
  </div>  
</template>

<script>  
import { requestsMixin } from "~/mixins/requestsMixin";  
const { getData } = require("country-list");

export default {  
  mixins: [requestsMixin],  
  data() {  
    return {  
      headlines: [],  
      countries: getData()  
    };  
  },  
  beforeMount() {  
    this.getHeadlinesByCountry();  
  },  
  methods: {  
    async getHeadlinesByCountry() {  
      this.country = this.$route.params.countryCode;  
      const { data } = await this.getHeadlines(this.country);  
      this.headlines = data.articles;  
    }, 

    getCountryName() {  
      const country = this.countries.find(  
        c => c.code == this.$route.params.countryCode  
      );  
      return country ? country.name : "";  
    }  
  }  
};  
</script>

在该文件中,咱们接受route参数,countryCode而后从该位置调用咱们以前制做并包含在此组件中的this.getHeadlines函数,requestsMixin以从News API获取标题。而后结果将显示在该template部分的Bootstrap卡中。在模板中,咱们经过从country-list数据中找到国家名称来得到国家名称。若是找不到标题,咱们会显示一条消息。一般,若是要制做一个接受URL参数的页面,则必须制做一个带有下划线做为第一个字符以及所需URL参数的变量名的文件。所以,在此示例中,_countryCode.vue中咱们将countryCode使用该参数this.$route.params.countryCode

接下来,index.vue在pages文件夹中,将现有代码替换为:

<template>  
  <div class="container">  
    <h1 class="text-center">Home</h1>  
    <div class="card" v-for="(h, i) of headlines" :key="i">  
      <div class="card-body">  
        <h5 class="card-title">{{h.title}}</h5>  
        <p class="card-text">{{h.content}}</p>  
        <button class="btn btn-primary" :href="h.url" target="_blank" variant="primary">Read</button>  
      </div>  
      <img :src="h.urlToImage" class="card-img-bottom" />  
    </div>  
  </div>  
</template>  
<script>  
import { requestsMixin } from "~/mixins/requestsMixin";  
const { getData } = require("country-list");

export default {  
  mixins: [requestsMixin],  
  data() {  
    return {  
      headlines: []  
    };  
  },  
  beforeMount() {  
    this.getHeadlinesByCountry();  
  },  
  methods: {  
    async getHeadlinesByCountry() {  
      const { data } = await this.getHeadlines("us");  
      this.headlines = data.articles;  
    }  
  }  
};  
</script>

<style>  
</style>

这使咱们能够在主页上显示美国的标题。它的工做原理与_countryCode.vue页面类似,不一样之处在于,咱们仅得到美国的头条新闻,而不接受URL参数来根据URL得到来自不一样国家/地区的头条新闻。

接下来,咱们create-env.js在项目的根文件夹中建立一个,并添加如下内容:

const fs = require('fs')  
fs.writeFileSync('./.env', `API_KEY=${process.env.API_KEY}`)

这使咱们能够部署到Netlify,由于咱们须要.env根据输入的环境变量动态建立文件。另外,咱们.env手动建立文件,而后将API_KEY键做为键,将News API API键做为值。

接下来的nuxt.config.js,咱们将现有代码替换为:

require("dotenv").config();  
const { getData } = require("country-list");

export default {  
  mode: "universal",  
  /*  
   ** Headers of the page  
   */  
  head: {  
    title: "News Website",  
    meta: [  
      { charset: "utf-8" },  
      { name: "viewport", content: "width=device-width, initial-scale=1" },  
      {  
        hid: "description",  
        name: "description",  
        content: process.env.npm_package_description || ""  
      }  
    ],  
    link: [  
      { rel: "icon", type: "image/x-icon", href: "/favicon.ico" },  
      {  
        rel: "stylesheet",  
        href:  
         "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"  
      }  
    ],  
    script: [  
      { src: "https://code.jquery.com/jquery-3.3.1.slim.min.js" },  
      {  
        src:  
          "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"  
      },  
      {  
        src:  
          "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"  
      }  
    ]  
  },  
  /*  
   ** Customize the progress-bar color  
   */  
  loading: { color: "#fff" },  
  /*  
   ** Global CSS  
   */  
  css: [],  
  /*  
   ** Plugins to load before mounting the App  
   */  
  plugins: [],  
  /*  
   ** Nuxt.js dev-modules  
   */  
  buildModules: [],  
  /*  
   ** Nuxt.js modules  
   */  
  modules: [  
    // Doc: https://axios.nuxtjs.org/usage    
    "@nuxtjs/axios",  
    "@nuxtjs/dotenv"  
  ],  
  /*  
   ** Axios module configuration  
   ** See https://axios.nuxtjs.org/options
   */  
  axios: {},  
  /*  
   ** Build configuration  
   */  
  build: {  
    /*  
     ** You can extend webpack config here  
     */  
    extend(config, ctx) {}  
  },  
  env: {  
    apiKey: process.env.API_KEY || ""  
  },  
  router: {  
    routes: [  
      {  
        name: "index",  
        path: "/",  
        component: "pages/index.vue"  
      },  
      {  
        name: "headlines-id",  
        path: "/headlines/:countryCode?",  
        component: "pages/headlines/_countryCode.vue"  
      }  
    ]  
  },  
  generate: {  
    routes() {  
      return getData().map(d => `headlines/${d.code}`);  
    }  
  }  
};

在head对象中,咱们更改了title以便显示所需的标题而不是默认标题。在link中,咱们添加了Bootstrap CSS,在script中,咱们添加了Bootstrap JavaScript文件和jQuery,它们是Bootstrap的依赖项。因为咱们要构建静态站点,所以不能使用BootstrapVue,由于它是动态的。咱们不但愿在生成的输出中使用任何动态JavaScript,所以咱们必须使用普通的Bootstrap。在modules中,咱们添加"@nuxtjs/dotenv"了从.env建立到Nuxt应用程序的文件中读取环境变量的功能。咱们还进行了添加,require("dotenv").config();以便咱们能够将process.env.API_KEY其添加到此配置文件中。咱们必须这样作,因此咱们没必要检入.env文件。在里面env部分,咱们有了apiKey: process.env.API_KEY || "",这是经过使用读取.env文件中的API KEY而得到的dotenv。

在router中,咱们定义了动态路由,以便当用户单击具备给定URL的连接或单击具备此类URL的连接时能够查看它们。Nuxt还使用这些路由来生成静态文件。在generate中,咱们定义了Nuxt遍历的路径,以生成静态网站的静态文件。在这种状况下,路由数组由咱们以前建立的标题页面的路由组成。它将遍历它们以获取它们的数据,而后渲染它们并从渲染的结果生成文件。文件夹结构将与路线相对应。所以,因为咱们path是/headlines/:countryCode,所以生成的工件将具备该headlines文件夹以及全部国家/地区代码做为子文件夹的名称,而且在每一个文件夹内将有一个index.html 与呈现的内容。

如今,咱们准备将咱们的网站部署到Netlify。经过转到https://www.netlify.com/建立一个Netlify账户。免费计划将知足咱们的需求。而后将代码提交到托管在GitHub,Gitlab或Bitbucket上的Git存储库。而后,当您登陆Netlify时,单击Git中的New site。从那里,您能够添加托管在其中一项服务中的Git存储库。而后,当要求您输入Build Command时,输入node ./create-env.js && npm run generate,发布目录将为dist。

以后,将.env文件中的API密钥输入到网站设置的“环境变量”部分,您能够经过单击“构建和部署”菜单上的“环境”连接来进入。输入API_KEY做为密钥,而后输入News API API密钥做为值。而后单击保存按钮。

一旦将全部内容提交并推送到由GitHub,Gitlab或Bitbucket托管的Git存储库中,Netlify将自动构建和部署。

原文连接:https://dev.to/aumayeung/generate-static-websites-with-nuxt-1ia1

相关文章
相关标签/搜索