Nuxt.js 基础语法

Nuxt.js 基础语法Nuxt 新增一个 Nuxt js 配置文件 router 注意 这样配置后路由地址都应该以 abc 开头 http localhost 3000 abc 要是访问首页的话就是 abc 末尾的 不

大家好,欢迎来到IT知识分享网。

在这里插入图片描述

一、概述

1. Nuxt.js是什么
  • 一个基于Vue.js生态的第三方开源服务端渲染应用框架
  • 它可以帮我们轻松的使用Vue.js技术栈构建同构应用
  • 官网: Nuxt.js – Vue.js 通用应用框架 | Nuxt.js 中文网
  • Github仓库: https://github.com/nuxt/nuxt.js

在这里插入图片描述

 

2. NuxtJS 使用方式
  • 初始项目,从零开始的方式
  • 已有的 Node.js 服务端项目的方式
    • 直接把 Nuxt 当作一个中间件集成到 Node Web Server 中
  • 现有的 Vue.js 项目基础上增加Nuxt的方式
    • 非常熟悉 Nuxt.js
    • 至少百分之 10 的代码改动

二、初始化 NuxtJS

Nuxt 提供了两种方式用来创建项目: 使用 create-nuxt-app 脚手架工具、手动创建,下面以手动创建为例:
 

1. 创建项目目录
# 创建项目 mkdir nuxt-app-demo ​ # 进入项目 cd nuxt-app-demo ​ # 初始化 package.json 文件 npm init -y ​ # 安装 nuxt npm install nuxt 
2. 配置项目启动命令

在 package.json文件的 scripts 中新增:

"scripts": { "dev": "nuxt" } 
3. 创建入口文件

根路径创建 pages 目录:

mkdir pages 

创建第一个页面的 pages/index.vue

<template> <h1>Hello world!</h1> </template> 
4. 启动项目
npm run dev 
  • 注意:Nuxt.js 会监听 pages 目录中的文件更改,因此在添加新页面时无需重新启动应用程序。
5. git托管

新建 .gitignore 文件:

# 排除不需要用git托管的文件 node_modules .nuxt 
6. git 分支
git branch # 看本地当前所在分支,并且在当前分支前面加“*”号标记 git branch -r # 查看远程分支,r是remote的简写 git branch _分支名 # 创建一个新的本地分支 git checkout 分支名 # 切换分支 git checkout -b 分支名 # 创建并切换分支 


三、路由

1. 基本路由
⑴. 文档说明

在这里插入图片描述
 

⑵. 项目代码:

新建 pages/user/one 文件:

<template> <h1>one</h1> </template> 

⑶. 预览:

在这里插入图片描述

2. 路由导航
  • a 标签: 会刷新整个页面,走服务端渲染,不要使用
  • nuxt-link: <nuxt-link to="/"> 主页 </nuxt-link>
  • 编程式导航: this.$router.push
     

编辑 pages/user/one 文件:

<template> <div> <h1>About page</h1> <!-- a 链接,刷新导航,走服务端渲染 --> <h2>a 链接</h2> <a href="/">首页</a> ​ <!-- router-link 导航链接组件 --> <h2>router-link</h2> <router-link to="/">首页</router-link> ​ <!-- 编程式导航 --> <h2>编程式导航</h2> <button @click="onClick">首页</button> </div> </template> ​ <script> export default { name: 'AboutPage', methods: { onClick () { this.$router.push('/') } } } </script> 

3. 动态路由

在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。

在这里插入图片描述

新建 pages/user/_id.vue 文件:

<template> <div> <h1>User Pages</h1> <!-- 路由参数 id 能够通过 $route.params.xx 的形式来获取 --> <h2>{ 
    { $route.params.id }}</h2> </div> </template> <script> export default { name: 'UserPage' } </script> 
4. 嵌套路由
  • 创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件
  • 在父组件(.vue文件) 内增加 用于显示子视图内容

在这里插入图片描述

5. 自定义路由配置

新增一个 nuxt.config.js 文件进行配置:

/ * Nuxt.js 配置文件 */ module.exports = { router: { base: '/abc' } } // 注意,这样配置后路由地址都应该以/abc开头:http://localhost:3000/abc/... // 要是访问首页的话就是abc/,末尾的/不能省略 

也可以使用 extendRoutes 方法

module.exports = { router: { base: '/abc', // routes: 一个数组,路由配置表 // resolve: 解析路由组件路径 extendRoutes(routes, resolve) { routes.push({ name: 'hello', path: '/hello', component: resolve(__dirname, 'pages/about.vue') }) } } } 


四、视图

1. 结构

在这里插入图片描述

在 NuxtJS 中页面结构一般由三部分组成:

  • 第一部分是最外层的文档页面,也就是单页面或者说服务端渲染的HTML页面。
  • 在HTML 页面里面包裹着 Layout布局组件(可选),相当于所有页面的父路由。
  • 再往里面是页面组件,每个页面组件有自己额外的成员方法,包括页面的子组件之类的可选内容。
2. 模板

定制化默认的 html 模板,只需要在根目录(或者 src)创建一个 app.html 的文件:

<!DOCTYPE html>
<html {
  
     
     
     
     
     
     
     { HTML_ATTRS }}> <head { 
     { HEAD_ATTRS }}> { 
     { HEAD }} </head> <body { 
     { BODY_ATTRS }}> { 
     { APP }}  <!-- 这body里就是渲染视图的位置,这个app就是根组件 -->
  </body>
</html>
3. 布局 (Layout)

可通过添加 layouts/default.vue 文件来扩展应用的默认布局:

<template> <div> <h2>layouts/default.vue</h2> <!-- 页面出口,类似子路由 --> <nuxt /> </div> </template> 

然后其他页面 (即 pages/index.vue ) 使用自定义布局:

<template> <h1>Hello world!</h1> </template> <script> export default { name: 'HomePage', // 在别的组件使用时指定layout:'foo' 也就是指定别的组件作为布局组件,也就是foo会代替default layout: 'default' // 表示使用默认布局使用的是 layouts文件夹下面的default组件 } </script> 

五、异步数据

1. asyncData 方法

asyncData方法会在组件(限于页面组件)每次加载之前被调用。它可以在服务端或路由更新之前被调用。在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,你可以利用 asyncData方法来获取数据,Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法返回的数据一并返回给当前组件。

  • 基本用法
    • 它会将asyncData返回的数据融合组件data方法返回数据一并给组件
    • 调用时机:服务端渲染期间和客户端路由更新之前(保证了服务端和客户端都要运行处理数据)
       
  • 注意事项
    • 只能在页面组件中使用,非页面组件中不会调用asyncData方法,如果子组件中需要数据,可以通过props方式传递数据
    • 没有this,因为它是在组件初始化之前被调用的
2. 代码演示

⑴. 添加数据

新建数据文件 static/data.json :

{ "posts": [ { "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, { "id": 2, "title": "qui est esse", "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }, { "id": 3, "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" }, { "id": 4, "title": "eum et est occaecati", "body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit" }, { "id": 5, "title": "nesciunt quas odio", "body": "repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque" } ], "title": "文章数据" } 

⑵. 获取数据

安装 axios

npm i axios 
  • 在首页直接获取数据(服务端获取异步数据):
<template> <div> <h1>{ 
     { title }}</h1> </div> </template> <script> import axios from 'axios' export default { name: 'HomePage', layout: 'default', async asyncData () { console.log('asyncData') console.log(this) const res = await axios({ method: 'GET', url: 'http://localhost:3000/data.json' }) return res.data }, data () { return { foo: 'bar' } } } </script> 

如果我们尝试在asyncData里面进行console.log(‘xxx’)时,会发现在服务端的控制台输出xxx的同时,nuxt为了方便调试和更加直观,会让客户端也会输出xxx,并且客户端的xxx是包裹在Nuxt SSR对象中的,如果尝试打印this会发现是undefined,因为服务端渲染时组件还没初始化。

⑶. 客户端路由导航
⑷. 子组件调用 asyncData 方法

注意: asyncData只能在页面组件中使用,不能在非页面组件(比如页面组件的子组件)中使用,非页面组件中不会调用asyncData函数如果想在子组件使用服务端渲染时的数据,只能通过页面组件进行获取,然后再利用父子组件中的传值方法来传递给页面组件的子组件

页面组件的子组件:

// components/Foo.vue <template> <div> <h1>FooPage</h1> <ul> <li v-for="item in posts" :key="item.id" > { 
     { item.title }} </li> </ul> </div> </template> <script> export default { name: 'FooPage', props: ['posts'], // asyncData 只能在页面组件中使用 // async asyncData () { // console.log('foo asyncData') // return { // foo: 'bar' // } // } } </script> 

页面组件:

// pages/index.vue <template> <div> <h1>{ 
     { title }}</h1> <nuxt-link to="/about">About</nuxt-link> <br> <foo :posts="posts" /> </div> </template> <script> import axios from 'axios' import Foo from '@/components/Foo' export default { name: 'HomePage', layout: 'default', components: { Foo }, // 当你想要动态页面内容有利于 SEO // 或者是提升首屏渲染速度的时候, // 就在 asyncData 中发请求拿数据 async asyncData () { console.log('asyncData') console.log(this) const res = await axios({ method: 'GET', url: 'http://localhost:3000/abc/data.json' }) return res.data }, // 如果是非异步数据或者普通数据,则正常的初始化到 data 中即可 data () { return { foo: 'bar' } } } </script> 

3. 上下文对象

比如:http:// localhost:3000/artical/5 这个路径就应该对应第五篇文章,那么问题是怎么获取这个5呢
首先我们容易想到路由对象 this.$route.params ,但是 asyncData 在服务端执行时是没有 this 的,也就是说 this 不指向当前 Vue 实例
所以我们需要使用 asyncData 中的上下文对象参数来获取,上下文对象中可以获取动态路由中的参数

// pages/article/_id.vue // 根据路径中的最后一位id值的不同来拿到不同的对象,然后渲染页面中的不同内容 <template> <div> <!-- <h1>article page</h1> --> <h1>{ 
     { article.title }}</h1> <div>{ 
     { article.body }}</div> </div> </template> <script> import axios from 'axios' export default { name: 'ArticlePage', // asyncData 上下文对象 async asyncData (context) { // 这里有我们需要的数据 console.log(context) const { data } = await axios({ method: 'GET', url: 'http://localhost:3000/data.json' }) // asyncData 里面没有 this, 不能通过这种方式获取 id // console.log(this.$route.params) // 可以通过上下文对象的 params.id 或者 router.params.id // 拿到后将字符串类型转换为数字类型 // 根据路径中的最后一位id值的不同来拿到不同的对象,然后渲染页面中的不同内容 const id = Number.parseInt(context.params.id) return { article: data.posts.find(item => item.id === id) } } } </script> 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/126674.html

(0)
上一篇 2025-09-16 20:15
下一篇 2025-09-16 20:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信