大前端学习 -- NuxtJS学习笔记

举报
楚楚冻人玥玥仙女 发表于 2021/11/19 02:33:55 2021/11/19
【摘要】 NuxtJS学习笔记 文章内容输出来源:大前端高薪训练营 代码仓库地址:https://gitee.com/jiailing/nuxtjs-demo,在多个分支里都有代码 一...

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. 动态路由

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 的子路由创建 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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。