超详细的 Nuxt 入门、实践与总结
Nuxt入门&实践总结
一、nuxt简介及安装
Nuxt.js 官方介绍:
Nuxt.js 是一个基于 Vue.js 的通用应用框架。通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。我们的目标是创建一个灵活的应用框架,你可以基于它初始化新项目的基础结构代码,或者在已有 Node.js 项目中使用 Nuxt.js,Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据加载、中间件支持、布局支持等。
1、nuxt简介
1)、那服务器端渲染的益处
nuxt.js
简单的说是Vue.js
的通用框架,最常用的就是用来作SSR(服务器端渲染)
。Vue.js
是开发SPA(单页应用)
的,Nuxt.js
这个框架,用Vue
开发多页应用,并在服务端完成渲染,可以直接用命令把我们制作的vue
项目生成为静态html
。
主要的原因时SPA(单页应用)
不利于搜索引擎的SEO
操作,Nuxt.js
适合作新闻、博客、电影、咨询这样的需要搜索引擎提供流量的项目。如果你要作移动端的项目,就没必要使用这个框架了。
2)、什么是SSR?
-
SSR
就是 服务器渲染,什么是 服务器渲染? - 由 服务器 组装好
DOM
元素,生成HTML
字符串给到浏览器,也就是在浏览器里面是可以看到整个页面的DOM
源码的。
3)、SSR解决的问题:
-
SEO
:搜索引擎的优先爬取级别是页面的HTML
结构,当我们使用SSR
的时候,服务端已经生成了与业务相关联的HTML
,这样的信息对于SEO
是很友好的。 -
内容呈现:客户端无需等待所有的
JS
文件加载完成即可看见渲染的业务相关视图(压力来到了服务端这边,这也是需要做权衡的地方,需要区分哪些由服务端渲染,哪些可以交给客户端)。
4)、SSR相关的弊端:
-
代码兼容:对于开发人员来讲,需要去兼容代码在不同环境的运行
Vue SSR
所需要的服务端环境是Node
,有一些客户端的对象,比如dom
、windows
之类的则无法使用。 -
服务器负载:相对于前后端分离模式下服务器只需要提供静态资源来说,
SSR
需要的服务器负载更大,所以在项目中使用SSR
模式要慎重,比如一整套图表页面,相对于服务端渲染,可能用户不会在乎初始加载的前几秒,可以交由客户端使用类似于骨架屏,或者懒加载之类的提升用户体验。
5)、Vue 与 Vue SSR 与 原生 HTML 页面源码区别对比
-
在网页上右键查看源码:
Vue SSR
与 原生HTML
是可以看到源码标签的 -
在认识
SSR
之前,首先对CSR
与SSR
之间做个对比。-
首先看一下传统的
web
开发,传统的web
开发是,客户端向服务端发送请求,服务端查询数据库,拼接HTML
字符串(模板),通过一系列的数据处理之后,把整理好的HTML
返回给客户端,浏览器相当于打开了一个页面。这种比如我们经常听说过的jsp
,PHP
,aspx
也就是传统的MVC
的开发。 -
SPA
应用,到了Vue
、React
,单页面应用优秀的用户体验,逐渐成为了主流,页面整体是javaScript
渲染出来的,称之为客户端渲染CSR
。SPA
渲染过程。由客户端访问URL
发送请求到服务端,返回HTML
结构(但是SPA
的返回的HTML
结构是非常的小的,只有一个基本的结构,如第一段代码所示)。客户端接收到返回结果之后,在客户端开始渲染HTML
,渲染时执行对应javaScript
,最后渲染template
,渲染完成之后,再次向服务端发送数据请求,注意这里时数据请求,服务端返回json
格式数据。客户端接收数据,然后完成最终渲染。(请求两次,百度搜索引擎不能抓取SPA
页面的数据) -
SPA
虽然给服务器减轻了压力,但是也是有缺点的:- 首屏渲染时间比较长:必须等待
JavaScript
加载完毕,并且执行完毕,才能渲染出首屏。 -
SEO
不友好:爬虫只能拿到一个div
元素,认为页面是空的,不利于SEO
。 为了解决如上两个问题,出现了SSR
解决方案,后端渲染出首屏的DOM
结构返回,前端拿到内容带上首屏,后续的页面操作,再用单页面路由和渲染,称之为服务端渲染(SSR
)。
- 首屏渲染时间比较长:必须等待
-
-
SSR
渲染流程是这样的,客户端发送URL
请求到服务端,服务端读取对应的url
的模板信息,在服务端做出html
和数据的渲染,渲染完成之后返回html
结构,客户端这时拿到的之后首屏页面的html
结构。所以用户在浏览首屏的时候速度会很快,因为客户端不需要再次发送ajax
请求。并不是做了SSR
我们的页面就不属于SPA
应用了,它仍然是一个独立的spa
应用。 -
SSR
是处于CSR
与SPA
应用之间的一个折中的方案,在渲染首屏的时候在服务端做出了渲染,注意仅仅是首屏,其他页面还是需要在客户端渲染的,在服务端接收到请求之后并且渲染出首屏页面,会携带着剩余的路由信息预留给客户端去渲染其他路由的页面。
6)、Nuxt.js是特点(优点):
- 基于`Vue``
- 自动代码分层
- 服务端渲染
- 强大的路由功能,支持异步数据
- 静态文件服务
-
EcmaScript6
和EcmaScript7
的语法支持 - 打包和压缩
JavaScript
和CSS
-
HTML
头部标签管理 - 本地开发支持热加载
- 集成
ESLint
- 支持各种样式预编译器
SASS
、LESS
等等 - 支持
HTTP/2
推送
2、nuxt安装
1)、安装
// 全局安装npx
npm install npx -g
// 使用npx创建nuxt项目
npx create-nuxt-app 项目名
Project name // 项目名称
Project description // 项目描述
Use a custom server framework // 选择服务器框架
Choose features to install // 选择安装的特性
Use a custom UI framework // 选择UI框架
Use a custom test framework // 测试框架
Choose rendering mode // 渲染模式
Universal // 渲染所有连接页面
Single Page App // 只渲染当前页面
当一个客户端请求进入的时候,服务端有通过nuxtServerInit
这个命令执行在Store
的action
中,在这里接收到客户端请求的时候,可以将一些客户端信息存储到Store
中,也就是说可以把在服务端存储的一些客户端的一些登录信息存储到Store
中。之后使用了中间件机制,中间件其实就是一个函数,会在每个路由执行之前去执行,在这里可以做很多事情,或者说可以理解为是路由器的拦截器的作用。然后再validate
执行的时候对客户端携带的参数进行校验,在asyncData
与fetch
进入正式的渲染周期,asyncData
向服务端获取数据,把请求到的数据合并到Vue
中的data
中
2)、目录结构
└─my-nuxt-demo
├─.nuxt // Nuxt自动生成,临时的用于编辑的文件,build
├─assets // 用于组织未编译的静态资源如LESS、SASS或JavaScript,对于不需要通过 Webpack 处理的静态资源文件,可以放置在 static 目录中
├─components // 用于自己编写的Vue组件,比如日历组件、分页组件
├─layouts // 布局目录,用于组织应用的布局组件,不可更改
├─middleware // 用于存放中间件
├─node_modules
├─pages // 用于组织应用的路由及视图,Nuxt.js根据该目录结构自动生成对应的路由配置,文件名不可更改
├─plugins // 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。
├─static // 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时 候,该目录下的文件会映射至应用的根路径 / 下。文件夹名不可更改。
└─store // 用于组织应用的Vuex 状态管理。文件夹名不可更改。
├─.editorconfig // 开发工具格式配置
├─.eslintrc.js // ESLint的配置文件,用于检查代码格式
├─.gitignore // 配置git忽略文件
├─nuxt.config.js // 用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。文件名不可更改。
├─package-lock.json // npm自动生成,用于帮助package的统一设置的,yarn也有相同的操作
├─package.json // npm 包管理配置文件
├─README.md
3)、配置文件nuxt.config.js
注意:
-
export default
在一个模块中只能有一个,当然也可以没有。export
在一个模块中可以有多个。 -
export default
的对象、变量、函数、类,可以没有名字。export
的必须有名字。 -
export default
对应的import
和export
有所区别 -
module
变量代表当前模块。这个变量是一个对象,module
对象会创建一个叫exports
的属性,这个属性的默认值是一个空的对象
Node
为每个模块提供一个exports
变量,指向module.exports
,两个是相等的关系,但又不是绝对相当的关系,module.exports
可以直接导出一个匿名函数或者一个值,但是export
的必须有名字,故不行,export default
或export
名字可以
const pkg = require('./package')
module.exports = {
mode: 'universal', // 当前渲染使用模式,分为universal和spa,既然是nuxt开发,那就是universal
// 全局页头配置 (https://go.nuxtjs.dev/config-head)
head: { // 页面head配置信息
title: pkg.name, // title
meta: [ // meat
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
// 这里可以添加网站验证码信息
// { name: 'google-site-verification', content: 'xxx' },
// 实测百度无法通过验证,此问题还没解决
// { name: 'baidu-site-verification', content: 'code-xxx' },
],
link: [ // favicon,若引用css不会进行打包处理
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
// nuxt 加载进度条配置 (https://zh.nuxtjs.org/api/configuration-loading)
loading: { color: '#fff' }, // 页面进度条
// 全局css (https://go.nuxtjs.dev/config-css)
css: [ // 全局css(会进行webpack打包处理)
'element-ui/lib/theme-chalk/index.css'
],
// 配置后,会在页面渲染之前加载 (https://go.nuxtjs.dev/config-plugins)
plugins: [ // 插件
'@/plugins/element-ui'
],
// 工具module (https://go.nuxtjs.dev/config-modules)
modules: [ // 模块
'@nuxtjs/axios',
],
// 如果添加了@nuxt/axios则会需要此配置来覆盖默认的一些配置 (https://go.nuxtjs.dev/config-axios)
axios: {
https: true,
progress: true, // 是否显示加载进度条
credentials: true, // 请求携带cookie
baseURL: 'https://www.abeille.top/api',
proxy: true // 请求代理,开发中跨域问题解决方法
},
// 打包配置 (https://go.nuxtjs.dev/config-build)
build: { // 打包
transpile: [/^element-ui/],
extend(config, ctx) { // webpack自定义配置
}
}
}
4)、Nuxt运行命令
{
"scripts": {
// 开发环境
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
// 打包
"build": "nuxt build",
// 在服务端运行
"start": "cross-env NODE_ENV=production node server/index.js",
// 生成静态页面
"generate": "nuxt generate"
}
}
二、nuxt常用配置
1、配置IP和端口
第一种 nuxt.config.js
:
module.exports = {
server: {
port: 8000,
host: '127.0.0.1'
}
}
第二种 package.json
:
"config": {
"nuxt": {
"port": "8000",
"host": "127.0.0.1"
}
}
2、配置全局CSS
在开发多页项目时,都会定义一个全局的CSS
来初始化我们的页面渲染,比如把padding
和margin
设置成0
,网上也有非常出名的开源css
文件normailze.css
。要定义这些配置,需要在nuxt.config.js
里进行操作。
比如现在我们要把页面字体设置为红色,就可以在assets/css/common.css
文件,然后把字体设置为红色。
/assets/css/common.css
html{
color:red;
}
body {
margin:0;
padding:0;
}
/nuxt.config.js
css:['~assets/css/normailze.css']
设置好后,在终端输入pm run dev
。然后你会发现字体已经变成了红色。
三、Nuxt的路由配置和参数传递
1、路由
Nuxt.js
的路由并不复杂,它给我们进行了封装,让我们节省了很多配置环节。
Nuxt
会自动生成路由,故而只需使用<nuxt-link :to=""> </nuxt-link>
,而非<router-link :to=""> </router-link>
页面跳转方式:
- 不要写成
a
标签,因为是重新获取一个新的页面,并不是SPA
<nuxt-link to="/users"></nuxt-link>
this.$router.push('/users')
动态路由:
- 在
Nuxt.js
里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的Vue
文件 或 目录。 - 获取动态参数
{{$route.params.id}}
2、路由传参
this.$route.query.key
的方式参数显示在地址栏上, 但是并不是我们想要的,:id?id=``?
所以建议还是尽量使用router-link
来实现跳转来解决地址栏的变化,更方便网站的优化
1)、nuxt-link中传递参数
方式一
传参:
<nuxt-link :to="{path:'/about',query:{index:id}}" target="_blank" ><nuxt-link>
地址栏显示:
loaclhost:3000/about/id
接收地址栏参数:
this.$route.query.index
方式二
传参:
<nuxt-link target="_blank" :to="{name: 'log-id', params:{id: n.id,key:value}}"></nuxt-link>
地址栏显示:
loaclhost:3000/about/id
接收:
async asyncData ({ params }) { // params.id 就是我们传进来的值}// 或者 created () { this.$route.params.xxx}`
2)、在方法中传递
方式一
跳转:
getDescribe(id) {
// 直接调用$router.push 实现携带参数的跳转
this.$router.push({
path: `/describe/${id}`,
})
接收:
$route.params.id
方式二
注意:
页面之间的跳转使用query 不然的话刷新页面后会找不到参数
跳转:
this.$router.push({
path: '/describe',
query: {
id: id
}
})
接收:
$route.query.id
3、路由传参校验
Nuxt.js
可以让你在动态路由对应的页面组件中配置一个validate
方法用于校验动态路由参数的有效性。该函数有一个布尔类型的返回值,如果返回true
则表示校验通过,如果返回false
则表示校验未通过。
export default {
// nuxt中使用validate方法进行路由参数校验,这个方法必须返回一个布尔值,为true表示校验通过,为false表示校验失败。注意validate不能写到methods属性中。
validate(obj) {
// console.log(obj);
// return true
return /^\d+$/.test(obj.params.id)
}
}
4、路由嵌套
注意:
在nuxt
框架中,在 nuxt.config.js
中components: true
已开启了组件自动导入,故而不需要在vue
文件中通过import
和components
来导入组件,只需在template
中写入相应组件的组件名即可
- 添加一个
Vue
文件,作为父组件 - 添加一个与父组件同名的文件夹来存放子视图组件
- 在父文件中,添加组件,用于展示匹配到的子视图
5、Nuxt的路由动画效果
路由的动画效果,也叫作页面的更换效果。Nuxt.js提供两种方法为路由提供动画效果,一种是全局的,一种是针对单独页面制作。
1)、全局路由动画
全局动画默认使用page来进行设置,例如现在我们为每个页面都设置一个进入和退出时的渐隐渐现的效果。我们可以先在根目录的assets/css
下建立一个normailze.css
文件。
(1)添加样式文件
/assets/css/normailze.css
(没有请自行建立)
.page-enter-active, .page-leave-active {
transition: opacity 2s;
}
.page-enter, .page-leave-active {
opacity: 0;
}
(2)文件配置
然后在nuxt.config.js
里加入一个全局的css
文件就可以了。
css:['assets/css/main.css']
这时候在页面切换的时候就会有2秒钟的动画切换效果了,但是你会发现一些页面是没有效果的,这是因为你没有是<nuxt-link>
组件来制作跳转链接。你需要进行更改。
<li><nuxt-link :to="{name:'news-id',params:{id:123}}">News-1</nuxt-link></li>
2)、单独设置页面动效
想给一个页面单独设置特殊的效果时,我们只要在css里改变默认的page,然后在页面组件的配置中加入transition字段即可。例如,我们想给about页面加入一个字体放大然后缩小的效果,其他页面没有这个效果。
(1)在全局样式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;
}
(2)然后在about/index.vue组件中设置
export default {
transition:'test'
}
这时候就有了页面的切换独特动效了。
总结:在需要使用的页面导入即可。
四、Nuxt的默认模版和默认布局
在开发应用时,经常会用到一些公用的元素,比如网页的标题是一样的,每个页面都是一模一样的标题。这时候我们有两种方法,第一种方法是作一个公用的组件出来,第二种方法是修改默认模版。这两种方法各有利弊,比如公用组件更加灵活,但是每次都需要自己手动引入;模版比较方便,但是只能每个页面都引入。
1、默认模板
Nuxt
为我们提供了超简单的默认模版订制方法,只要在根目录下创建一个app.html
就可以实现了。现在我们希望每个页面的最上边都加入“学习nuxt.js” 这几个字,我们就可以使用默认模版来完成。
app.html中:
<!DOCTYPE html>
<html lang="en">
<head>
{{ HEAD }}
</head>
<body>
<p>学习nuxt.js</p>
{{ APP }}
</body>
</html>
这里的{{ HEAD }}
读取的是nuxt.config.js
里的信息,{{APP}}
就是我们写的pages
文件夹下的主体页面了。需要注意的是HEAD
和APP
都需要大写,如果小写会报错的。
注意:如果你建立了默认模板后,记得要重启服务器,否则显示不会成功;但是默认布局是不用重启服务器的。
2.默认布局
默认模板类似的功能还有默认布局,但是从名字上你就可以看出来,默认布局主要针对于页面的统一布局使用。它在位置根目录下的layouts/default.vue
。需要注意的是在默认布局里不要加入头部信息,只是关于<template>
标签下的内容统一订制。
需求:我们在每个页面的最顶部放入“学习nuxt.js” 这几个字,看一下在默认布局里的实现。
<template>
<div>
<p>学习nuxt.js</p>
<nuxt/>
</div>
</template>
这里的<nuxt/>
就相当于我们每个页面的内容,你也可以把一些通用样式放入这个默认布局里,但会增加页面的复杂程度。
总结:要区分默认模版和默认布局的区别,模版可以订制很多头部信息,包括IE
版本的判断;模版只能定制<template>
里的内容,跟布局有关系。在工作中修改时要看情况来编写代码。
五、Nuxt插件的使用
1、ElementUI使用
(1)、下载npm i element-ui -S
(2)、在plugins
文件夹下面,创建ElementUI.js
文件
import Vue from 'vue'
import ElementUI from 'element-ui'
Vue.use(ElementUI)
(3)、在nuxt.config.js
中添加配置
css: [
'element-ui/lib/theme-chalk/index.css'
],
plugins: [
{src: '~/plugins/ElementUI', ssr: true }
],
build: {
vendor: ['element-ui']
}
2、Element按需引入
1)、下载依赖:
# 先下载element-ui
npm install element-ui --save
# 如果使用按需引入,必须安装babel-plugin-component(官网有需要下载说明,此插件根据官网规则不同,安装插件不同)
npm install babel-plugin-component --save-dev
安装好以后,按照nuxt.js
中的规则,你需要在 plugins/
目录下创建相应的插件文件
在文件根目录创建(或已经存在)plugins/
目录,创建名为:element-ui.js
的文件,内容如下:
import Vue from 'vue'
import { Button } from 'element-ui' //引入Button按钮
export default ()=>{
Vue.use(Button)
}
2)、引入插件
在nuxt.config.js
中,添加配置为:plugins
css:[
'element-ui/lib/theme-chalk/index.css'
],
plugins:[
'~/plugins/element-ui'
]
默认为:开启SSR
,采用服务端渲染,也可以手动配置关闭SSR,配置为:
css:[
'element-ui/lib/theme-chalk/index.css'
],
plugins:[
{
src:'~/plugins/element-ui',
ssr:false //关闭ssr
}
]
3)、配置babel
选项
在nuxt.config.js
中,配置在build
选项中,规则为官网规则:
build: {
babel:{ //配置按需引入规则
"plugins":[
[
"component",
{
"libraryName":"element-ui",
"styleLibraryName":"theme-chalk"
}
]
]
},
/*
** Run ESLINT on save
*/
extend (config, ctx) {
if (ctx.isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
}
}
3、axios的使用
(1)、安装npm install --save axios
(2)、使用
import axios from 'axios'
asyncData(context, callback) {
axios.get('http://localhost:3301/in_theaters')
.then(res => {
console.log(res);
callback(null, {list: res.data})
})
}
(3)、为防止重复打包,在nuxt.config.js
中配置
module.exports = {
build: {
vendor: ['axios']
}
}
4、vuex的使用
Nuxt.js
内置引用了 vuex
模块,所以不需要额外安装。
Nuxt.js
会找到应用根目录下的 store
目录,如果该目录存在,它将做以下的事情:
- 引用 vuex 模块
- 将 vuex 模块 加到 vendors 构建配置中去
- 设置 Vue 根实例的 store 配置项
Nuxt.js
支持两种使用 store
的方式,你可以择一使用:
- 模块方式: store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index 是根模块)
- 普通方式: store/index.js 返回一个 Vuex.Store 实例(官方不推荐)
模块方式
状态树还可以拆分成为模块,store
目录下的每个 .js
文件会被转换成为状态树指定命名的子模块
使用状态树模块化的方式,store/index.js
不需要返回 Vuex.Store
实例,而应该直接将 state、mutations 和 actions
暴露出来:
index.js
export const state = () => ({
articleTitle: [],
labelList: []
})
export const mutations = {
// 设置热门文章标题
updateArticleTitle(state, action) {
state.articleTitle = action
},
// 设置标签列表数据
updateLabel(state, action){
state.labelList = action
}
}
export const actions = {
// 获取热门文章标题
fetchArticleTitle({ commit }) {
return this.$axios
.$get('http://localhost:3000/article/title')
.then(response => {
commit('updateArticleTitle', response.data)
})
},
// 获取标签
fetchLabel({ commit }) {
return this.$axios
.$get('http://localhost:3000/label/list')
.then(response => {
commit('updateLabel', response.data)
})
}
}
index.vue
fetch
方法中触发异步提交状态事件
<script>
import ArticleList from '~/components/archive/list'
import Banner from '~/components/archive/banner'
export default {
components: {
ArticleList,
Banner,
},
async asyncData({ app }){
//获取文章列表数据
let article = await app.$axios.get(`http://localhost:3000/article/list?pageNum=1&pageSize=5`)
return {articleList: article.data.data}
},
async fetch({ store }) {
return Promise.all([
store.dispatch('common/fetchArticleTitle'),
store.dispatch('common/fetchLabel')
])
},
computed: {
},
methods: {
}
}
</script>
对应组件中通过computed
方法获取状态数据
computed: {
labelList(){
return this.$store.state.common.labelList
}
}
六、Nuxt的错误页面和个性meta设置
当用户输入路由错误的时候,我们需要给他一个明确的指引,所以说在应用程序开发中404页面是必不可少的。Nuxt.js
支持直接在默认布局文件夹里建立错误页面。
1、建立错误页面
在根目录下的layouts
文件夹下建立一个error.vue
文件,它相当于一个显示应用错误的组件。
<template>
<div>
<h2 v-if="error.statusCode==404">404页面不存在</h2>
<h2 v-else>500服务器错误</h2>
<ul>
<li><nuxt-link to="/">HOME</nuxt-link></li>
</ul>
</div>
</template>
<script>
export default {
props:['error']
}
</script>
代码用v-if
进行判断错误类型,需要注意的是这个错误是你需要在<script>
里进行声明的,如果不声明程序是找不到error.statusCode
的。
这里我也用了一个<nuxt-link>
的简单写法直接跟上路径就可以了。
2、个性meta设置
页面的Meta
对于SEO
的设置非常重要,比如你现在要作个新闻页面,那为了搜索引擎对新闻的收录,需要每个页面对新闻都有不同的title
和meta
设置。直接使用head
方法来设置当前页面的头部信息就可以了。我们现在要把New-1
这个页面设置成个性的meta
和title
。
(1)、我们先把pages/news/index.vue
页面的链接进行修改一下,传入一个title
,目的是为了在新闻具体页面进行接收title
,形成文章的标题。
/pages/news/index.vue
<li><nuxt-link :to="{name:'news-id',params:{id:123,title:'nuxt.com'}}">News-1</nuxt-link></li>
(2)、第一步完成后,我们修改/pages/news/_id.vue
,让它根据传递值变成独特的meta
和title
标签。
<template>
<div>
<h2>News-Content [{{$route.params.id}}]</h2>
<ul>
<li><a href="/">Home</a></li>
</ul>
</div>
</template>
<script>
export default {
validate ({ params }) {
// Must be a number
return /^\d+$/.test(params.id)
},
data(){
return{
title:this.$route.params.title,
}
},
//独立设置head信息
head(){
return{
title:this.title,
meta:[
{hid:'description',name:'news',content:'This is news page'}
]
}
}
}
</script>
注意:为了避免子组件中的meta
标签不能正确覆盖父组件中相同的标签而产生重复的现象,建议利用 hid
键为meta
标签配一个唯一的标识编号。
七、asyncData方法获取数据
Nuxt.js
贴心的为我们扩展了Vue.js
的方法,增加了anyncData
,异步请求数据。
1、三种方式
Nuxt.js
提供了几种不同的方法来使用 asyncData
方法,你可以选择自己熟悉的一种来用:
- 返回一个
Promise
, nuxt.js会等待该Promise
被解析之后才会设置组件的数据,从而渲染组件 - 使用
async
或await
- 使用回调函数
返回Promise
export default {
asyncData ({ params }) {
return axios.get(`https://my-api/posts/${params.id}`)
.then((res) => {
return { title: res.data.title }
})
}
}
使用async或await
export default {
async asyncData ({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
使用回调函数
export default {
asyncData ({ params }, callback) {
axios.get(`https://my-api/posts/${params.id}`)
.then((res) => {
callback(null, { title: res.data.title })
})
}
}
安装Axios
Vue.js
官方推荐使用的远程数据获取方式就Axios
,所以我们安装官方推荐,来使用Axios
。这里我们使用npm
来安装 axios
。 直接在终端中输入下面的命令:
npm install axios --save
2、ansycData的promise方法
我们在pages
下面新建一个文件,叫做ansyData.vue
。然后写入下面的代码:
<script>
import axios from 'axios'
export default {
data(){
return {
name:'hello World',
}
},
asyncData(){
return axios.get('接口')
.then((res)=>{
console.log(res)
return {info:res.data}
})
}
}
</script>
asyncData的方法会把值返回到data中。是组件创建(页面渲染)之前的动作,所以不能使用this.info
return的重要性
一定要return出去获取到的对象,这样就可以在组件中使用,这里返回的数据会和组件中的data合并。这个函数不光在服务端会执行,在客户端同样也会执行。
3、ansycData的promise并发应用
async asyncData(context) {
let [newDetailRes, hotInformationRes, correlationRes] = await Promise.all([
axios.post('http://www.huanjingwuyou.com/eia/news/detail', {
newsCode: newsCode
}),
axios.post('http://www.huanjingwuyou.com/eia/news/select', {
newsType: newsType, // 资讯类型: 3环评资讯 4环评知识
start: 0, // 从第0条开始
pageSize: 10,
newsRecommend: true
}),
axios.post('http://www.huanjingwuyou.com/eia/news/select', {
newsType: newsType, // 资讯类型: 3环评资讯 4环评知识
start: 0, // 从第0条开始
pageSize: 3,
newsRecommend: false
})
])
return {
newDetailList: newDetailRes.data.result,
hotNewList: hotInformationRes.data.result.data,
newsList: correlationRes.data.result.data,
newsCode: newsCode,
newsType: newsType
}
}
4、ansycData的await方法
当然上面的方法稍显过时,现在都在用ansyc…await
来解决异步,改写上面的代码。
<script>
import axios from 'axios'
export default {
data(){
return {
name:'hello World',
}
},
async asyncData(){
let {data}=await axios.get('接口')
return {info: data}
}
}
</script>
5、注意事项+生命周期:
-
asyncData
方法会在组件(限于页面组件)每次加载之前被调用 -
asyncData
可以在服务端或路由更新之前被调用 - 第一个参数被设定为当前页面的上下文对象
-
Nuxt
会将asyncData
返回的数据融合到组件的data
方法返回的数据一并返回给组件使用 - 对于
asyncData
方式是在组件初始化前被调用的,所以在方法内饰没办法通过this
来引用组件的实例对象
八、静态资源和打包
1、静态资源
(1)直接引入图片
在网上任意下载一个图片,放到项目中的static文件夹下面,然后可以使用下面的引入方法进行引用
<div><img src="~static/logo.png" /></div>
“~”就相当于定位到了项目根目录,这时候图片路径就不会出现错误,就算打包也是正常的。
(2)CSS引入图片
如果在CSS
中引入图片,方法和html
中直接引入是一样的,也是用“~”符号引入。
<style>
.diss{
width: 300px;
height: 100px;
background-image: url('~static/logo.png')
}
</style>
推荐阅读
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇
### MySQL索引底层解析与优化实战
- 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少?
- Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理
- Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开
- Zookeeper是个啥?特性和应用场景大公开
- ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节
- 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用
- Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位
- RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略
- 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南
- RocketMQ特性和应用场景揭示:理解其精髓与差异化优势
- Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析
- ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用
- MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学
- BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用
- Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析
- 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示
- 解密Netty粘包与拆包现象,怎样有效应对这一常见问题
- 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术
- Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处
- Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现
-----------------------
七、结语与回顾
-
超详细的 Nuxt 入门、实践与总结
-
玩转Kotlin性能测试:JMH入门指南一 - 测试基础"
"深入理解JMH在Kotlin中的应用:基准测试实战解析"
"轻松实践Kotlin基准测试:JMH工具详解与实例总结
-
入门级前端工程实践构建:HTML与JS的加载流程详细解析