Nuxt
概述
- 一个基于Vue.js生态的第三方开源服务端渲染应用框架
- 它可以帮我们轻松的使用Vue.js技术栈构建同构应用
路由
基本路由
Nuxt.js 依据 pages
目录结构自动生成 vue-router 模块的路由配置。
假设 pages
的目录结构如下:
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
那么,Nuxt.js 自动生成的路由配置如下:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'user',
path: '/user',
component: 'pages/user/index.vue'
},
{
name: 'user-one',
path: '/user/one',
component: 'pages/user/one.vue'
}
]
}
路由导航
-
a标签
它会刷新整个页面,不要使用
-
nuxt-link
组件用法类似
router-link
<nuxt-link to="/">首页</nuxt-link>
-
编程式导航
用法类似
$router
this.$router.push('/'); // this.$router.push({name:'index'});
动态路由
在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。
pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue
Nuxt.js 生成对应的路由配置表为:
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}
你会发现名称为 users-id
的路由路径带有 :id?
参数,表示该路由是可选的。如果你想将它设置为必选的路由,需要在 users/_id
目录内创建一个 index.vue
文件。
可以通过this.$route.xx
获取路由参数。
嵌套路由
创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue
Nuxt.js 自动生成的路由配置如下:
router: {
routes: [
{
path: '/users',
component: 'pages/users.vue',
children: [
{
path: '',
component: 'pages/users/index.vue',
name: 'users'
},
{
path: ':id',
component: 'pages/users/_id.vue',
name: 'users-id'
}
]
}
]
}
自定义路由配置
在项目中创建nuxt.config.js,使用CommonJS规范导出一个配置对象。
// nuxt.config.js
module.exports = {
router: {
// 修改根路径 http://localhost:3000/abc/xx
base: '/abc',
// 添加自定义路由
extendRoutes(routes, resolve) {
routes.push({
name: 'custom',
path: '*',
component: resolve(__dirname, 'pages/404.vue')
})
},
...
},
}
视图
视图-模板
定制化默认的 html 模板,只需要在 src 文件夹下(默认是应用根目录)创建一个 app.html
的文件
默认模板为:
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
举个例子,你可以修改模板添加 IE 的条件表达式:
<!DOCTYPE html>
<!--[if IE 9]><html lang="en-US" class="lt-ie9 ie9" {{ HTML_ATTRS }}><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html {{ HTML_ATTRS }}><!--<![endif]-->
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
视图-布局
Nuxt.js 允许你扩展默认的布局,或在 layout
目录下创建自定义的布局。
提示: 别忘了在布局文件中添加 <nuxt/>
组件用于显示页面的主体内容。
-
默认布局
可通过添加
layouts/default.vue
文件来扩展应用的默认布局。默认布局的源码如下:
<template> <nuxt /> </template>
-
自定义布局
layouts
目录中的每个文件 (顶级) 都将创建一个可通过页面组件中的layout
属性访问的自定义布局。假设我们要创建一个 博客布局 并将其保存到
layouts/blog.vue
:<template> <div> <div>我的博客导航栏在这里</div> <nuxt /> </div> </template>
然后我们必须告诉页面 (即
pages/posts.vue
) 使用您的自定义布局:<template> <!-- Your template --> </template> <script> export default { layout: 'blog' // page component definitions } </script>
异步数据
Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData
的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。
asyncData
-
作用
获取异步请求的数据,并将其设置到组件data中。
-
基本用法
asyncData
方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用asyncData
方法来获取数据,Nuxt.js 会将asyncData
返回的数据融合组件data
方法返回的数据一并返回给当前组件。 -
注意事项
由于
asyncData
方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过this
来引用组件的实例对象。 只能在页面组件中使用,不能在Component组件中调用。
-
使用时机
当你想要动态页面内容有利于SEO,或者是提升首屏渲染速度时,可以在asyncData中发送异步请求获取数据。
监听 query 参数改变
默认情况下,query 的改变不会调用asyncData
方法。如果要监听这个行为,例如,在构建分页组件时,您可以设置应通过页面组件的watchQuery
属性监听参数。
监听参数字符串更改并在更改时执行组件方法 (asyncData, fetch, validate, layout, …)
- 类型:
Boolean
orArray
(默认:[]
)
使用watchQuery
属性可以监听参数字符串的更改。 如果定义的字符串发生变化,将调用所有组件方法(asyncData, fetch, validate, layout, …)。 为了提高性能,默认情况下禁用。
如果您要为所有参数字符串设置监听, 请设置: watchQuery: true
.
export default {
watchQuery: ['page']
}
上下文对象
asyncData的第一个参数为当前页面的上下文对象,通过上下文对象可以:
-
在服务器端调用
asyncData
时,您可以访问用户请求的req
和res
对象。export default { async asyncData({ req, res }) { // 请检查您是否在服务器端 // 使用 req 和 res if (process.server) { return { host: req.headers.host } } return {} } }
-
访问动态路由数据
export default { async asyncData({ params }) { const slug = params.slug // When calling /abc the slug will be "abc" return { slug } } }
-
监听 query 参数改变
默认情况下,query 的改变不会调用
asyncData
方法。如果要监听这个行为,例如,在构建分页组件时,您可以设置应通过页面组件的watchQuery
属性监听参数。 -
错误处理
Nuxt.js 在上下文对象
context
中提供了一个error(params)
方法,你可以通过调用该方法来显示错误信息页面。params.statusCode
可用于指定服务端返回的请求状态码。 以返回
Promise
的方式举个例子:export default { asyncData({ params, error }) { return axios .get(`https://my-api/posts/${params.id}`) .then(res => { return { title: res.data.title } }) .catch(e => { error({ statusCode: 404, message: 'Post not found' }) }) } }
如果你使用
回调函数
的方式, 你可以将错误的信息对象直接传给该回调函数, Nuxt.js 内部会自动调用error
方法:export default { asyncData({ params }, callback) { axios .get(`https://my-api/posts/${params.id}`) .then(res => { callback(null, { title: res.data.title }) }) .catch(e => { callback({ statusCode: 404, message: 'Post not found' }) }) } }