[技术翻译]使用Nuxt生成静态网站
本周再来翻译一些技术文章,本次预计翻译三篇文章如下:
我翻译的技术文章都放在一个github仓库中,如果觉得有用请点击star收藏。我为什么要创建这个git仓库?目的是通过翻译国外的web相关的技术文章来学习和跟进web发展的新思想和新技术。git仓库地址:
静态网站如今再次流行起来了。信息站和品牌宣传站不再需要使用wordpress之类的内容管理系统来动态更新。
使用静态网站生成器,您可以从无源cms,api等动态源以及markdown文件等文件中获取内容。
nuxt是基于vue.js的出色的静态网站生成器,可轻松用于构建静态网站。使用nuxt,从动态内容构建静态网站所需要做的就是创建模板,以从api和markdown文件等动态源动态显示内容。然后,在nuxt配置文件中,我们静态定义路由,以便它可以通过相同的路由将内容生成为静态文件。
在本文中,我们将使用nuxt构建新闻网站,并将使用https://newsapi.org/
的news api 作为内容。您必须先了解vue.js,然后才能使用nuxt建立网站,因为nuxt是基于vue.js的框架。
首先,我们在news api网站上注册api密钥。如果我们只想获取头条新闻,它是免费的。我们开始来使用nuxt cli构建网站。我们通过键入以下命令来运行:
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将自动构建和部署。
原文链接:
下一篇: WPF自定义控件的制作