大前端学习 -- NuxtJS学习笔记
NuxtJS学习笔记
文章内容输出来源:大前端高薪训练营
代码仓库地址:https://gitee.com/jiailing/nuxtjs-demo,在多个分支里都有代码
一、Nuxt.js是什么
- 一个基于Vue.js生态的第三方开源服务端渲染应用框架
- 它可以帮我们轻松的使用Vue.js技术栈构建同构应用
- 官网:https://zh.nuxtjs.org/
- Github仓库:https://github.com/nuxt/nuxt.js
二、Nuxt.js的使用方式
- 初始化项目
- 已有的Node.js服务端项目
- 直接把Nuxt当做一个中间件集成到Node Web Server中
- 现有的Vue.js项目
- 非常熟悉Nuxt.js
- 至少百分之10的代码改动
三、初始化Nuxt.js应用方式
官方文档:https://zh.nuxtjs.org/guide/installation
- 方式一:使用create-nuxt-app
- 方式二:手动创建
四、Nuxt.js路由
1. 基本路由
pages文件夹下的文件会自动生成路由
2. 路由导航
-
a标签
- 它会刷新整个页面,不推荐使用
<a href="/">首页</a>
-
nuxt-link组件
- https://router.vuejs.org/zh/api/#router-link-props
<router-link to="/">首页</router-link>
-
编程式导航
-
https://router.vuejs.org/zh/guide/essentials/navigation.html
-
<button @click="onClick">首页</button>
methods: { onClick () { this.$router.push('/') } }
- 1
- 2
- 3
- 4
- 5
-
3. 动态路由
- Vue Router动态路由匹配
- https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html
- Nuxt
user/_id.vue,动态路由参数文件名由下划线开头。
<template>
<div>
<h1>User page</h1>
<p>{{$route.params.id}}</p>
</div>
</template>
<script>
export default {
name: 'UserPage'
}
</script>
<style scoped>
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
4. 嵌套路由
- Vue Router 嵌套路由
- https://router.vuejs.org/zh/guide/essentials/nested-routes.html
- Nuxt.js嵌套路由
可以通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由。创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
Warning: 别忘了在父组件(.vue
文件) 内增加 <nuxt-child/>
用于显示子视图内容。
4. 路由配置
-
参考文档:https://zh.nuxtjs.org/api/configuration-router
-
在项目根目录下创建nuxt.config.js
/** * Nuxt.js 配置文件 nuxt.config.js */ module.exports = { router: { base: '/abc', // routes就是路由配置表,是个数组,resolve是解析路由路径的 extendRoutes(routes, resolve) { routes.push({ name: 'custom', path: '*', component: resolve(__dirname, 'pages/404.vue') }), routes.push({ name: 'hello', path: '/hello', component: resolve(__dirname, 'pages/about.vue') }) } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
五、Nuxt.js视图
1. 模板
你可以定制化 Nuxt.js 默认的应用模板。
定制化默认的 html 模板,只需要在 src 文件夹下(默认是应用根目录)创建一个 app.html
的文件。
默认模板为:
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2. 结构
Nuxt.js 允许你扩展默认的布局,或在 layout
目录下创建自定义的布局。
可通过添加 layouts/default.vue
文件来扩展应用的默认布局。
提示: 别忘了在布局文件中添加 <nuxt/>
组件用于显示页面的主体内容。
默认布局的源码如下:
<template>
<nuxt />
</template>
- 1
- 2
- 3
可以在组件中通过layout属性修改默认布局组件:
Index页面的布局组件变成了foo,但是about页面还是default,因为about页面没有修改其layout属性,所以默认的布局文件还是default
六、Nuxt.js异步数据
1. asyncData方法
Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData
的方法,使得我们可以在设置组件的数据之前能异步获取或处理数据。
- https://zh.nuxtjs.org/guide/async-data
- 基本用法
- 它会将asyncData返回的数据融合组件data方法返回数据一并给组件
- 调用时机:服务端渲染期间和客户端路由更新之前(保证了服务端和客户端都要运行处理数据)
- 注意事项
- 只能在页面组件中使用,非页面组件中不会调用asyncData方法,如果子组件中需要数据,可以通过props方式传递数据
- 没有this,因为它是在组件初始化之前被调用的
当你想用的动态页面内容有利于SEO或者是提升首屏渲染速度的时候,就在asyncData中发送请求数据。如果是非异步数据或者普通数据,则正常的初始化到data中即可。
Pages/index.vue
<template>
<div>
<h1>Hello {{ title }}!</h1>
<Foo />
<nuxt-link to="/about">about</nuxt-link>
</div>
</template>
<script>
import axios from 'axios'
import Foo from '@/components/Foo'
export default {
name: 'HomePage',
components: {
Foo
},
async asyncData () {
// 如果验证asyncData是在服务端执行的?可以通过log输出在了服务端控制台,得出这个方法是在服务端执行的。Nuxtjs为了方便调试,把服务端控制台输出数据也打印在了客户端控制台,但是为了区分,在客户端控制台用“Nuxt SSR”包裹起来了
console.log('asyncData')
const res = await axios({
method: 'GET',
url: 'http://localhost:3000/data.json'// 这里的请求地址要写完整,因为在服务端渲染期间,也要来请求数据,不写完整的话服务端渲染就会走到80端口,如果只是客户端渲染,就会以3000端口为基准来请求根目录下的data.json,服务端渲染就默认走到80了
})
// 返回的数据会与data中的数据混合
return res.data
},
data () {
return {
foo: 'bar'
}
}
}
</script>
<style scoped>
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
pages/components/Foo.vue
<template>
<div>
<h1>Foo</h1>
此处会报错,因为这是非页面组件,asyncData方法不会执行,所以foo是未定义。
<h3>{{foo}}</h3>
</div>
</template>
<script>
export default {
name: 'FooPage',
asyncData () {
return {
foo: 'bar'
}
}
}
</script>
<style scoped>
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
static这个文件夹可以直接作为根路径访问
2. 上下文对象
pages/article/_id.vue
<template>
<div>
<h1>article Page </h1>
<nuxt-link to="/">首页</nuxt-link>
<h3>title: {{post.title}}</h3>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'ArticlePage',
async asyncData (context) {
// asyncData的参数为上下文对象,我们无法在这个方法里使用this,所以无法通过this.$router.params.id拿到路由参数,但是可以通过context.params.id获取参数
console.log(context)
const { data: {posts} } = await axios({
method: 'GET',
url: 'http://localhost:3000/data.json'
})
const id = parseInt(context.params.id, 10)
return {
post: posts.find(item => item.id === id),
}
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
Components/Foo.vue
<template>
<div>
<h1>Foo</h1>
<ul>
<li v-for="item in posts" :key="item.id">
<nuxt-link :to="'/article/'+item.id">{{item.title}}</nuxt-link>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'FooPage',
props: ["posts"]
}
</script>
<style scoped>
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
pages/index.vue
<template>
<div>
<h1>Hello {{ title }}!</h1>
<Foo :posts="posts" />
<nuxt-link to="/about">about</nuxt-link>
</div>
</template>
<script>
import axios from 'axios'
import Foo from '@/components/Foo'
export default {
name: 'HomePage',
components: {
Foo
},
async asyncData () {
// 如果验证asyncData是在服务端执行的?可以通过log输出在了服务端控制台,得出这个方法是在服务端执行的。Nuxtjs为了方便调试,把服务端控制台输出数据也打印在了客户端控制台,但是为了区分,在客户端控制台用“Nuxt SSR”包裹起来了
console.log('asyncData')
const res = await axios({
method: 'GET',
url: 'http://localhost:3000/data.json'// 这里的请求地址要写完整,因为在服务端渲染期间,也要来请求数据,不写完整的话服务端渲染就会走到80端口,如果只是客户端渲染,就会以3000端口为基准来请求根目录下的data.json,服务端渲染就默认走到80了
})
// 返回的数据会与data中的数据混合
return res.data
},
data () {
return {
foo: 'bar'
}
}
}
</script>
<style scoped>
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
文章来源: blog.csdn.net,作者:爱玲姐姐,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/jal517486222/article/details/107810075
- 点赞
- 收藏
- 关注作者
评论(0)