Nuxt.js 是一个基于 Vue.js 的通用应用框架,通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI渲染。
Nuxt.js 简单的说就是 Vue.js 的通用框架,最常用的就是用来作 SSR(服务器端渲染)。再直白点说,就是 Vue.js 原来是开发 SPA(单页应用)的,但是随着技术的普及,很多人想用 Vue 开发多页应用,并在服务端完成渲染。这时候就出现了 Nuxt.js 这个框架,她简化了 SSR 的开发难度。还可以直接用命令把我们制作的 vue 项目生成为静态 html(我们也称这个技术解决方案为 SSG)。
项目搭建与配置
npx create-nuxt-app nuxt-demo
然后按照需要进行配置项选择
当运行完时,它将安装所有依赖项,因此下一步是启动项目:
cd
npm run dev
应用现在运行在 http://localhost:3000 上运行。
|-- .nuxt // Nuxt自动生成,临时的用于编辑的文件,build
|-- assets // 用于组织未编译的静态资源入LESS、SASS 或 JavaScript
|-- components // 用于自己编写的Vue组件,比如滚动组件,日历组件,分页组件
|-- layouts // 布局目录,用于组织应用的布局组件,不可更改。
|-- middleware // 用于存放中间件
|-- pages // 用于存放写的页面,我们主要的工作区域
|-- plugins // 用于存放JavaScript插件的地方
|-- static // 用于存放静态资源文件,比如图片
|-- store // 用于组织应用的Vuex 状态管理。
|-- .editorconfig // 开发工具格式配置
|-- .eslintrc.js // ESLint的配置文件,用于检查代码格式
|-- .gitignore // 配置git不上传的文件
|-- nuxt.config.json // 用于组织Nuxt.js应用的个性化配置,已覆盖默认配置
|-- package-lock.json // npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
|-- package-lock.json // npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
|-- package.json // npm包管理配置文件
别名 | 目录 |
---|---|
~ |
|
或 @ |
srcDir |
~~ |
|
或 @@ |
rootDir |
开发中经常会遇到端口被占用或者指定 IP 的情况。我们需要在根目录下的 package.json 里对 config 项进行配置。比如现在我们想把 IP 配置成 127.0.0.1,端口设置 1818
"config":{
"nuxt":{
"host":"127.0.0.1",
"port":"1818"
}
},
配置好后,我们在终端中输入npm run dev,然后你会看到服务地址改为了127.0.0.1:1818.
在开发多页项目时,都会定义一个全局的 CSS 来初始化我们的页面渲染,比如把 padding 和 margin 设置成 0,网上也有非常出名的开源 css 文件 normailze.css,要定义这些配置,需要在nuxt.config.js里进行操作。
比如现在我们要把页面字体设置为红色,就可以在 assets/css/normailze.css 文件,然后把字体设置为红色。
PS:如果使用 scss 需要安装依赖 npm install --save-dev node-sass sass-loader
/* assets/css/normailze.css */
html{
color:red;
}
// nuxt.config.js
css:['~assets/css/normailze.css']
在 nuxt.config.js 里是可以对 webpack 的基本配置进行覆盖的,比如现在我们要配置一个 url-loader 来进行小图片的64位打包。就可以在 nuxt.config.js 的 build 选项里进行配置。
// 自定义 webpack 配置
build: {
transpile: [/^element-ui/],
extend (config, { isDev, isClient }) {
// 音频文件 file-loader 处理,使用
npm install cross-env --save
配置各个环境下的接口地址和服务端口
export default {
dev: {
server: {
host: '0.0.0.0',
port: 8888,
},
api: {
port: '',
host: '开发环境接口地址'
}
},
test: {
server: {
host: '0.0.0.0',
port: 7085,
},
api: {
port: '',
host: '测试环境接口地址''
}
},
uat: {
server: {
host: '0.0.0.0',
port: 7085,
},
api: {
port: '',
host: '预发布环境接口地址''
}
},
prod: {
server: {
host: '0.0.0.0',
port: 7085,
},
api: {
port: '',
host: '生产环境接口地址''
}
}
}
import env from './env';
export default {
env:{
MODE:process.env.MODE
},
axios: {
baseURL: env[process.env.MODE].api.host,
},
//修改默认的访问端口
server: env[process.env.MODE].server,
}
学习前端框架都要学习路由机制,因为路由可以体现我们的业务逻辑,把模块串联起来,让程序焕发光彩。那简单的说路由就是我们的跳转机制,也可以简单理解成链接跳转。Nuxt.js 的路由并不复杂,它给我们进行了封装,让我们节省了很多配置环节。
1. 简单路由Demo
我们现在根目录的pages文件下新建两个文件夹,about
和 news
,在 about
文件夹下新建 index.vue
文件
<template>
<div>
<h2>About Index pageh2>
<ul>
<li><a href="/"Home>a>li>
ul>
div>
template>
在 news
文件夹下新建 index.vue
文件
<template>
<div>
<h2>News Index pageh2>
<ul>
<li><a href="/"Home>a>li>
ul>
div>
template>
修改原来的 pages 文件夹下的 index.vue
<template>
<div>
<ul>
<li><a href="/"HOME>a>li>
<li><a href="/about"ABOUT>a>li>
<li><a href="/news">NEWSa>li>
ul>
div>
template>
标签
虽然上面的例子跳转已经成功,但是 Nuxt.js 并不推荐这种标签的作法,它为我们准备了
标签(vue中叫组件),我们先把首页的标签替换成
。
<template>
<div>
<ul>
<li><nuxt-link :to="{name:'index'}">HOMEnuxt-link>li>
<li><nuxt-link :to="{name:'about'}">ABOUTnuxt-link>li>
<li><nuxt-link :to="{name:'news'}">NEWSnuxt-link>li>
ul>
div>
template>
我们再次预览页面,也是可以进行正常跳转的,在实际开发中尽量使用标签的方法跳转路由。
2. params传递参数
路由经常需要传递参数,我们可以简单的使用 params 来进行传递参数,我们现在向新闻页面(news)传递个参数,然后在新闻页面进行简单的接收。
我们先修改 pages
下的 Index.vue
文件,给新闻的跳转加上 params 参数,传递 3306 ID。注意:一般情况下我们不推荐这种传递参数方法,因为我们一刷新,参数立马就丢失了!
<template>
<div>
<ul>
<li><nuxt-link :to="{name:'index'}">HOMEli>
<li><nuxt-link :to="{name:'about'}">ABOUTli>
<li><nuxt-link :to="{name:'news',params:{newsId:3306}}">NEWSli>
ul>
div>
template>
在 news
文件夹下的 index.vue
里用 $route.params.newsId
进行接收
<template>
<div>
<h2>News Index pageh2>
<p>NewsID:{{$route.params.newsId}}p>
<ul>
<li><a href="/"Home>a>li>
ul>
div>
template>
简单的路由已经弄清楚了,这节看一下动态路由,其实动态路由就是带参数的路由。比如我们现在新闻模块下面有很多新闻详细页,这时候就需要动态路由的帮助了。
1. 新闻详细页面传递参数
在 news 文件夹下面新建了 _id.vue 的文件,以下画线为前缀的 Vue 文件就是动态路由,然后在文件里边有 $route.params.id
来接收参数。
<template>
<div>
<h2>News-Content [{{$route.params.id}}]h2>
<ul>
<li><a href="/"Home>a>li>
ul>
div>
template>
修改新闻首页路由,我们在 /pages/news/index.vue
进行修改,增加两个详细页的路由
<template>
<div>
<h2>News Index pageh2>
<p>NewsID:{{$route.params.newsId}}p>
<ul>
<li><a href="/"Home>a>li>
<li><a href="/news/123">News-1a>li>
<li><a href="/news/456">News-2a>li>
ul>
div>
template>
2. 路由动态参数校验
进入一个页面,对参数传递的正确性校验是必须的,Nuxt.js
也贴心的为我们准备了校验方法 validate( )
export default {
validate ({ params }) {
// Must be a number
return /^\d+$/.test(params.id)
}
}
我们使用了validate方法,并把params传递进去,然后用正则进行了校验,如果正则返回了true正常进入页面,如果返回false进入404页面。
路由的动画效果,也叫作页面的更换效果。Nuxt.js提供两种方法为路由提供动画效果,一种是全局的,一种是针对单独页面制作。
1. 全局路由动画设置
全局动画默认使用 page 来进行设置,例如现在我们为每个页面都设置一个进入和退出时的渐隐渐现的效果。我们可以先在根目录的 assets/css 下建立一个 main.css 文件
.page-enter-active, .page-leave-active {
transition: opacity 1s;
}
.page-enter, .page-leave-active {
opacity: 0;
}
然后在 nuxt.config.js 里加入一个全局的 css 文件就可以了
css:['assets/css/main.css']
这时候在页面切换的时候就会有2秒钟的动画切换效果了,但是你会发现一些页面是没有效果的,这是因为你没有是
比如我们上节课作的动态路由新闻页,你就需要改成下面的链接,改过之后你就会看到动画效果了
<li><nuxt-link :to="{name:'news-id',params:{id:123}}">News-1nuxt-link>li>
2. 单独设置页面动效
想给一个页面单独设置特殊的效果时,我们只要在 css 里改变默认的 page,然后在页面组件的配置中加入transition 字段即可。例如,我们想给about页面加入一个字体放大然后缩小的效果,其他页面没有这个效果。
在全局样式 assets/main.css 中添加以下内容。
.test-enter-active, .test-leave-active {
transition: all 2s;
font-size:12px;
}
.test-enter, .test-leave-active {
opacity: 0;
font-size:40px;
}
然后在 about/index.vue 组件中设置,这时候就有了页面的切换独特动效了。
export default {
transition:'test'
}
在开发应用时,经常会用到一些公用的元素,比如网页的标题是一样的,每个页面都是一模一样的标题。这时候我们有两种方法,第一种方法是作一个公用的组件出来,第二种方法是修改默认模版。这两种方法各有利弊,比如公用组件更加灵活,但是每次都需要自己手动引入;模版比较方便,但是只能每个页面都引入。这节课我们就学习一下如何使用 Nuxt 的默认模版和默认布局功能。
1. 默认模板
Nuxt 为我们提供了超简单的默认模版订制方法,只要在根目录下创建一个 app.html 就可以实现了。现在我们希望每个页面的最上边都加入 「学而时习之,不亦说乎」这几个字,我们就可以使用默认模版来完成。
DOCTYPE html
<html lang="en">
<head>
{{ HEAD }}
head>
<body>
<p>学而时习之,不亦说乎p>
{{ APP }}
body>
html>
这里的 {{ HEAD }}
读取的是 nuxt.config.js
里的信息,{{ APP }}
就是我们写的 pages
文件夹下的主体页面了。需要注意的是 HEAD
和 APP
都需要大写,如果小写会报错的。这里还有一个小坑需要大家注意,就是如果你建立了默认模板后,记得要重启服务器,否则你的显示不会成功;但是默认布局是不用重启服务器的。
2. 默认布局
和默认模板类似的功能还有默认布局,但是从名字上你就可以看出来,默认布局主要针对于页面的统一布局使用。它在位置根目录下的 layouts/default.vue
。需要注意的是在默认布局里不要加入头部信息,只是关于标签下的内容统一订制。
还是上边的需求,我们在每个页面的最顶部放入「有朋自远方来,不亦说乎」这几个字,看一下在默认布局里的实现。
<template>
<div>
<p>有朋自远方来,不亦说乎p>
<nuxt/>
div>
template>
这里的
就相当于我们每个页面的内容,你也可以把一些通用样式放入这个默认布局里,但是个人不建议这样写,会增加页面的复杂程度。
当用户输入路由错误的时候,我们需要给他一个明确的指引,所以说在应用程序开发中 404 页面是必不可少的。Nuxt.js 支持直接在默认布局文件夹里建立错误页面。
1. 建立错误页面
在根目录下的 layouts 文件夹下建立一个 error.vue 文件,它相当于一个显示应用错误的组件。
<template>
<div>
<h2 v-if="error.statusCode==404">404页面不存在h2>
<h2 v-else>500服务器错误h2>
<ul>
li>
ul>
div>
template>
<script>
export default {
props:['error'],
}
script>
代码用 v-if 进行判断错误类型,需要注意的是这个错误是你需要在
二、使用 nuxtServerInit 方法调用 Vuex
如果在状态树中指定了 nuxtServerInit 方法,Nuxt.js 调用它的时候会将页面的上下文对象作为参数传给它,当我们想将服务端的一些数据传到客户端时,这个方法是非常好用的。
举个例子,假设我们服务端的会话状态树里可以通过 req.session.user 来访问当前登录的用户。将该登录用户信息传给客户端的状态树,我们只需更新 store/index.js 如下:
PS:关于 context 上下文对象,官方文档,非常重要要仔细理解和学习,这玩意是连接服务端和客户端的关键桥梁
const store = () = new Vuex.Store({
state: {
},
mutations: {
},
modules: {
user
},
actions:{
nuxtServerInit ({ commit }) {
console.log("nuxtServerInit is runing 哈哈哈哈")
// 服务端这里首次被调用
commit('user/M_LOGIN', '01-犬夜叉')
}
}
})
三、使用 middleware 构建中间件服务
// 在 middleware 文件夹中创建一个 auth.js 文件
export default function ({ store, route }){
console.log("中间件被执行了")
console.log(route)
store.commit("user/M_LOGIN", '02-黑猫警长')
}
// 在 nuxt.config.js 文件中路由拦截全局使用
router: {
middleware: 'auth'
}
// 在 page 页面中设置使用
Secret page
**四、在 asyncData 中调用 vuex **
asyncData 方法一般用来进行服务端数据初始化操作,同时也可以根据上下文去设置 store 信息
export default {
asyncData({ store }){
console.log("asyncData is runing")
// store.commit("user/M_LOGIN", '蜡笔小新')
store.dispatch("user/login", '03-樱桃小丸子')
},
}
五、使用 fetch 方法调用 Vuex
fetch 方法会在渲染页面前被调用,作用是填充状态树 store 数据,与 asyncData 方法类似,不同的是它不会设置组件的数据,也就是说单纯的在服务端进行数据初始化操作。
如果页面组件设置了fetch方法,它会在组件每次加载前被调用(在服务端或切换至目标路由之前),此方法需要跟服务端的人员配合
export default {
fetch({ store }){
console.log("fetch is runing")
// store.commit("user/M_LOGIN", '蜡笔小新')
store.dispatch("user/login", '04-樱桃小丸子')
},
}
Nuxt 是 Vue 项目服务器端渲染(SSR)解决方案。而在使用时,就会遇到前后端分离情况下的域名或端口不一致导致的跨域问题。本文将介绍如何通过设置代理解决 Nuxt 与 axios 集成的跨域问题。
Nuxt 使用 axios 为避免出现前端页面跨域问题,需要安装 @nuxtjs/axios 和 @nuxtjs/proxy 两个模块。**注意:**不需要手动注册 @nuxtjs/proxy 模块,但是必须要确保它在依赖项中
用 yarn 安装:
yarn add axios @nuxtjs/axios @nuxtjs/proxy
使用 npm 安装:
npm install axios @nuxtjs/axios @nuxtjs/proxy
安装完成后在 nuxt.config.js 文件里面添加以下配置:
module.exports = {
// 配置相关依赖模块
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
axios: {
// 是否开启代理
proxy: true,
// 尝试请求次数
retry: { retries: 3 },
//开发模式下开启debug
debug: process.env._ENV == "production" ? false : true,
// headers 设置
headers: { 'Content-Type': 'application/json', 'crossDomain': true },
timeout: 5000,
// 设置一个请求 baseUrl 这个要与 proxy 中保持一致
prefix: "/api"
},
proxy: {
'/api': {
target: 'http://ts.lagou.uieee.com/api/v2', // 目标接口域名
changeOrigin: true, // 表示是否跨域
pathRewrite: {
'^/api': '/', // 把 /api 替换成 /
}
}
},
build: {
// 防止多次打包
vendor: ["axios"]
}
}
创建 nuxt 插件,更改全局配置全局配置自定义 axios,在 plugins/ 目录下新建 axios.js 文件:
// plugins/axios.js
export default function({ $axios, redirect }) {
console.log('axios 请求插件被调用了!')
$axios.onResponse(res = {
return res.data
})
$axios.onError(error = {
const code = parseInt(error.response && error.response.status)
if (code === 404) {
redirect("/")
}
});
}
在 nuxt.config.js 中配置 axios.js 插件:
module.exports = {
plugins: ["@/plugins/axios"],
}
通过上面的设置后,使用 axios 插件需要注意的是在 asyncData 内和在 asyncData 外的使用是所不同的。
在 asyncData 里使用,服务端请求数据
// 请求数据,该方法会运行在服务器端
async asyncData( context ){
let res = await context.$axios.get("/feeds")
return {
newsList: res.feeds
}
}
在 asyncData 外使用,客户端请求数据
async mounted(){
let res = await this.$axios.get("/feeds")
console.log(res.feeds )
}
Nuxt 使用 create-nuxt-app 创建项目时,选择使用 Element-UI 为默认组件库,发现 Nuxt 没有开启 Element-UI 的按需引入配置,需要自行配置。
在 create-nuxt-app 中没有选择 Element-UI 的先安装。
npm install element-ui --save
或者
yarn add element-ui
Element-UI 开启按需引入,必须安装 babel-plugin-component 插件。
npm install babel-plugin-component --save-dev
或者
yarn add babel-plugin-component
// element-ui.js
import Vue from 'vue'
import {
Container,
Header,
Aside,
Main,
Menu,
MenuItem,
Button,
Form,
FormItem,
Input
} from 'element-ui'
const components = [
Container,
Header,
Aside,
Main,
Menu,
MenuItem,
Button,
Form,
FormItem,
Input
];
const Element = {
install (Vue) {
components.forEach(component = {
Vue.component(component.name, component)
})
}
}
// 全局引入
// import Element from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'
Vue.use(Element, { locale })
module.exports = {
plugins: ["@/plugins/element-ui"],
}
PS:Nuxt 默认为开启 SSR,采用服务端渲染,也可以手动配置关闭 SSR,配置为:
module.exports = {
plugins: [
{
src: "@/plugins/element-ui",
ssr: false // 关闭ssr
}
],
}
module.exports = {
css: ['element-ui/lib/theme-chalk/index.css'],
}
module.exports = {
build: {
// 按需引入 element 的样式 webpack 配置
babel: {
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
}
}
到此,Element-UI 按需引入配置完成。
在 Nuxt 中配置多语言站点逻辑相当复杂,要非常清晰理解到「服务端/客户端」之间的每个关键环节,还要理解多语言模式下的 ElementUI 插件的同步关系等。
npm install nuxt-i18n -S
yarn add nuxt-i18n
lang/zh.js 配置中文站点下的语言包信息
const zh = {
home:'首页',
news:'新闻中心',
aboutus: '关于我们',
musicPlayer:'音乐播放器'
}
export default zh
lang/en.js 配置英文站点下的语言包信息
const en = {
home:'Home',
news:'NewsList',
aboutus: 'AboutUs',
musicPlayer:'MusicPlayer'
}
export default en
lang/Index.js 组合 element-ui 语言包信息及默认语言包配置信息
import zh from "./zh.js";
import en from "./en.js";
// 加载element-ui语言包
import enLocale from "element-ui/lib/locale/lang/en";
import zhLocale from "element-ui/lib/locale/lang/zh-CN";
// const mergeZH = Object.assign(zhLocale, zh);
// const mergeEN = Object.assign(enLocale, en);
const mergeZH = { ...zhLocale, ...zh };
const mergeEN = { ...enLocale, ...en };
const langSet = {
fallbackLocale: "zh",
messages: {
en: mergeEN,
zh: mergeZH
}
};
export default langSet;
import Vue from 'vue'
import VueI18n from 'vue-i18n'
// 引入语言包配置的相关信息
import langSet from '../lang/index'
// 引入 element 配置的语言包信息
import elementLocale from 'element-ui/lib/locale'
Vue.use(VueI18n)
export default ({ app, store }) = {
app.i18n = new VueI18n({
// 要在 store 中配置相应的语言状态,这个状态会在中间件 middleware 中调用(实现客户端、服务端信息共用)
locale: store.state.user.lang,
...langSet
})
// 按需加载配置element
elementLocale.i18n((key, value) = app.i18n.t(key, value))
}
plugins: [
"@/plugins/axios.js",
"@/plugins/element-ui.js",
"@/plugins/i18n.js"
]
const state = () = ({
lang: 'zh',
langs: ['zh', 'en'],
})
const mutations = {
M_SET_LANG(state, lang){
state.lang = lang
}
}
const actions = {
setLang({ commit }, lang) {
commit("M_SET_LANG", lang);
},
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
export default function ({ isHMR, app, store, route, params, redirect }) {
// 如果从热模块替换调用中间件,则忽略它
if (isHMR) {
return
}
// 获取语言包中设置的默认语言
const defaultLang = app.i18n.fallbackLocale
// 获取 state 中保存当前语言状态
const lang = store.state.user.lang || defaultLang
// 获取 state 中保存的允许语言种类数组
const langs = store.state.user.langs
// 获取 url 路径中配置的语言状态
const urlLang = params.lang
// 如果路由没有传递 lang 参数,或者传递的参数不在 langs 数组中
if (!urlLang || !langs.includes(urlLang)) {
// 如果语言状态设置异常,则追加语言路由地址
return redirect('/' + lang + route.fullPath)
} else if(urlLang !== lang){
// 在 store 中设置新的语言
store.commit('user/M_SET_LANG', urlLang)
// 设置语言为新的语言体系
app.i18n.locale = urlLang
}
}
router: {
middleware: ["auth", "i18n"]
},
// 自定义 webpack 配置
build: {
// 防止多次打包
vendor: ["axios", "vue-i18n"],
transpile: [/^element-ui/]
}
页组件
|-- layouts // 布局目录,用于组织应用的布局组件,不可更改。
|-- middleware // 用于存放中间件
|-- pages // 用于存放写的页面,我们主要的工作区域
|-- |-- _lang
|-- |-- |-- index.vue
|-- |-- |-- about
|-- |-- |-- |-- index.vue
<template>
<div>
<header>
<nuxt-link to="/">{{ $t("home") }}nuxt-link>
<nuxt-link to="/news">{{ $t("news") }}nuxt-link>
<nuxt-link to="/about">{{ $t("aboutus") }}nuxt-link>
header>
<Nuxt />
div>
template>
<template>
<div class="news">
<nuxt-link v-for="(item, index) in newsList" :key="index" :to=" '/news/' + item.id ">
<el-button type="success">{{item.title}}el-button>
nuxt-link>
div>
template>
<script>
export default {
// 请求数据,该方法会运行在服务器端
async asyncData( context ){
let res = await context.$axios.get("http://localhost:4000/news-list?num=10&lang="+context.store.state.user.lang)
return {
newsList: res.list
}
}
}
script>
<template>
<div class="about">
<h2> {{title}} h2>
div>
template>
<script>
import {
mapState
} from 'vuex'
export default {
computed: {
...mapState('user',[
'lang'
]),
title(){
if(this.lang === 'zh'){
return '关于我们'
}else{
return 'About us'
}
}
}
}
script>
<template>
<div>
<header>
<nuxt-link to="/">{{ $t("home") }}nuxt-link>
<nuxt-link to="/news">{{ $t("news") }}nuxt-link>
<nuxt-link to="/about">{{ $t("aboutus") }}nuxt-link>
header>
<Nuxt />
<footer>
<el-button v-for="(item, index) in langs"
:key="index"
:disabled="item === lang? true : false"
:type=" item === lang ? 'success':'primary' "
@click="changeLang(item)">{{item}}el-button>
footer>
div>
template>
<script>
import {
mapState,
mapActions
} from 'vuex'
export default {
data() {
return {};
},
computed: {
...mapState('user',[
'lang','langs'
])
},
methods:{
...mapActions('user', [
"setLang"
]),
changeLang(lang){
// vuex 修改语言状态
this.setLang(lang)
// 通知 i18n 修改语言状态(仅仅为前端语言状态的改变)
this.$i18n.locale = lang
// 一旦监听到语言发生改变,则回到系统首页
this.$router.push("/")
}
}
};
script>
到此为止,我们终于完成了所有的逻辑配置,这个时候我们 ElementUI 中的语言状态也会同步发生更新
Generate 静态化打包的目的是为了能够生产出对应的静态文件,这里我们现在需要实现的目的是:
// 指定渲染输出的语言类目下的文件体系
generate: {
// nuxt generate 生成的目录名称
dir: 'jxnuxt',
// Nuxt.js 在生成静态文件时使用 html-minifier 对 html 文件进行压缩,配置压缩的行为
minify: {
collapseBooleanAttributes: true,
collapseWhitespace: false,
decodeEntities: true,
minifyCSS: true,
minifyJS: true,
processConditionalComments: true,
removeAttributeQuotes: false,
removeComments: false,
removeEmptyAttributes: true,
removeOptionalTags: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: false,
removeTagWhitespace: false,
sortAttributes: true,
sortClassName: false,
trimCustomFragments: true,
useShortDoctype: true
},
// 直接配置的路由在 Nuxt.js 执行 generate 命令时,动态路由 会被忽略
// routes: ['/cn', '/en', '/cn/news', '/en/news']
// 动态参数返回 Promise 对象类型,函数回调是 callback(err, params)
async routes(callback) {
const langs = ["/en", "/zh"];
const urls = ["/", "/news", "/about"];
const routes = [];
langs.map(lang = {
urls.map(url = {
routes.push(lang + url);
});
});
let res = await axios.get(
"http://localhost:4000/news-list?num=10&lang=en"
);
res.data.list.map(item = {
routes.push("/en/news/" + item.id);
});
let resq = await axios.get(
"http://localhost:4000/news-list?num=10&lang=zh"
);
resq.data.list.map(item = {
routes.push("/zh/news/" + item.id);
});
callback(null, routes);
}
}
}