nuxtjs初步学习

608 阅读9分钟

官网:Nuxt:直观的 Vue 框架 · Nuxt - Nuxt 中文 (nuxtjs.org.cn)

视频教程 Vue_SSR(服务端渲染)/Nuxt3全栈开发19分钟极速上手教程,vue-ssr服务端渲染入门教程,2023年最新Nuxt3全栈开发快速入门教程哔哩哔哩bilibili

什么是nuxt

nuxt是一个js开发框架,提供了响应式和组件,是基于vue

nuxt使用vue作为框架的"视图引擎"

nuxt还具有服务端能力

是基于nitro伺服器引擎,一个为达高效能与可移植性目标而构建的最小http框架

nuxt是一个兼具前端开发与后端开发的全栈开发框架

客户端渲染和服务端渲染

客户端渲染不能看到源代码,服务端可以看到源代码

优缺点

服务端利于seo,能够更快的首屏加载

spa 客户端渲染:

缺点:首屏加载所有资源,拖慢加载时间

优点:后续访问和页面切换速度快,而服务器压力小

ssr 服务端渲染:

优点:首屏加载快

缺点:后续访问的页面切换加大服务器压力,高并发时更明显

nuxt安装与使用

打开需要创建项目的目录,打开终端输入

npx nuxi@latest init <project-name>
  • Node.js - v18.0.0 或更高版本 确保使用偶数版本号(18、20 等)
  • 文本编辑器 - 我们推荐使用 Visual Studio Code,并安装 官方 Vue 扩展(以前称为 Volar)
  • 终端 - 用于运行 Nuxt 命令
PS F:\nasGit\study\nuxtjs> npx nuxi@latest init one
​
✔ Which package manager would you like to use?
npm
◐ Installing dependencies...                                                                                                                                                                                        11:12:27
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'cssnano@7.0.6',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'cssnano-preset-default@7.0.6',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'cssnano-utils@5.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-calc@10.0.2',
npm WARN EBADENGINE   required: { node: '^18.12 || ^20.9 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-colormin@7.0.2',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-convert-values@7.0.4',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-discard-comments@7.0.3',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-discard-duplicates@7.0.1',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-discard-empty@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-discard-overridden@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-merge-longhand@7.0.4',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-merge-rules@7.0.4',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-minify-font-values@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-minify-gradients@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-minify-params@7.0.2',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-minify-selectors@7.0.4',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-charset@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-display-values@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-positions@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-repeat-style@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-string@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-timing-functions@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-unicode@7.0.2',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-url@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-normalize-whitespace@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-ordered-values@7.0.1',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-reduce-initial@7.0.2',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-reduce-transforms@7.0.0',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'postcss-unique-selectors@7.0.3',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: 'stylehacks@7.0.4',
npm WARN EBADENGINE   required: { node: '^18.12.0 || ^20.9.0 || >=22.0' },
npm WARN EBADENGINE   current: { node: 'v18.0.0', npm: '8.19.2' }
npm WARN EBADENGINE }
npm WARN deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm WARN deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm WARN deprecated glob@8.1.0: Glob versions prior to v9 are no longer supported
npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm WARN deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm WARN deprecated npmlog@5.0.1: This package is no longer supported.
npm WARN deprecated are-we-there-yet@2.0.0: This package is no longer supported.
npm WARN deprecated gauge@3.0.2: This package is no longer supported.
​
> postinstall
> nuxt prepare
​
ℹ Compiled plugins/server.mjs in 5967.01ms                                                                                                                                                                         11:15:16   
ℹ Compiled plugins/client.mjs in 6080.57ms                                                                                                                                                                         11:15:16   
ℹ Compiled types/plugins.d.ts in 6112.61ms                                                                                                                                                                         11:15:16   
✔ Types generated in .nuxt                                                                                                                                                                                         11:15:17   
​
added 644 packages in 3m
​
128 packages are looking for funding
  run `npm fund` for details
✔ Installation completed.                                                                                                                                                                                          11:15:17   
​
✔ Initialize git repository?
No
                                                                                                                                                                                                                    11:16:50  
✨ Nuxt project has been created with the v3 template. Next steps:
 › cd one                                                                                                                                                                                                           11:16:50  
 › Start development server with npm run dev

使用vscode打开项目,打开app.vue

响应式

修改代码如下,验证响应式

<script setup lang="ts">
let aa = ref(777)
</script>
<template>
  <div>
    <NuxtRouteAnnouncer />
    <!-- <NuxtWelcome /> -->
     <h1>78979</h1>
     <h2>{{ aa }}</h2>
     <input type="text" v-model="aa">
  </div>
</template>

image-20240919115709175

组件

在根目录下面创建components,这是Nuxt约定的组件位置,默认会是全局组件

创建一个test.vue文件

<script setup lang="ts">
defineProps({
  msg: {
    type: String,
    default: 'Hello nuxt.js'
  }
});
​
</script><template>
  <div>测试</div>
  <div>{{ msg }}</div>
</template>
<style lang="scss">
  
</style>

app.vue里面使用

 <test msg="7897987"></test>

如果项目没有更新,直接重启项目就可以

路由

在根目录下面创建/pagesnuxt约定的路由放置目录,创建此目录之后,系统将在底层调用vue-router进行路由

创建/pages目录之后开启了路由,/app.vue会影响路由和页面,建议删掉或更改名称,但是app.vue也是主页入口,所以删除之后,建议创建新的主页

删除之后再/pages目录下创建index.vue文件当做新的主页

经过以上操作,主页就变成了index.vue页面

/pages目录下创建one.vue并编写内容保存,在地址栏中添加/one路径就能看到one.vue文件中的内容,如果输入一个不存在的地址就会返回404

总结

基本上和使用vue3没有什么区别,相当于省略了全局组件的配置和导入、路由的配置、省略了ref等的导入

nuxt服务端

路由

在项目根目录创建/servernuxt约定的服务端目录名称,用于后端开发

/server目录下可以有apiroutermiddlewareplugin等,教程中只说了api

  • api 用于存放接口; 内的文件在它们的路由中会自动加上 /api 前缀。要添加没有 /api 前缀的服务器路由,请将它们放入 routes 目录中
  • middleware 中间件 中间件处理程序将在任何其他服务器路由之前运行,以添加或检查标头、记录请求或扩展事件的请求对象
  • plugins Nuxt 会自动读取中的任何文件,并将它们注册为 Nitro 插件。这允许扩展 Nitro 的运行时行为并挂钩到生命周期事件。
  • utils 服务器路由由 unjs/h3 提供支持,它附带了一套方便的助手函数。目录中可以添加更多助手函数。
export default defineEventHandler((event) => {
    
})

api 路由 中间件均需要此函数

api目录下创建csapi.js

export default defineEventHandler((event) => {
​
    // 通过return 的方式进行返回数据  可以直接返回json对象
    return {
        status:1,
        msg:"hello world"
    }
})

启动项目之后访问接口地址是localhost:3000/api/csapi

  • localhost:3000 项目启动的地址
  • api表示请求的后台的api
  • csapi /server/api中创建的接口文件名

接口传参

在地址栏中添加一个参数localhost:3000/api/csapi?id=1

在文件中获取参数使用nuxt提供的getQuery()方法

image-20240919144125702

总结

使用起来还算可以,项目分工明确,应该会比较好用,具体的还有在后面学习

扩展

前端页面调用接口

在上面有了前端的页面,也有了后端的接口,那么在前端界面如何调用后端的接口在教程中并没有说

参考文章Nuxt3数据请求及封装_nuxt3 请求封装-CSDN博客

Nuxt3提供了多种方法来处理应用程序中的数据获取:

  • $fetch
  • useFetch
  • useLazyFetch
  • useAsyncData
  • useLazyAsyncData

Nuxt3 不推荐也没必要使用Axios进行网络请求,Axios本来是对 XMLHttpRequest 的封装,而现如今网络请求这种功能由 XMLHttpRequest 逐渐被 Fetch API 代替,浏览器已支持原生支持fetch,Node v17.5也引入了对fetch的原生支持。Nuxt3的官方团队将fetch进一步封装,封装的项目叫做ofetch,并且将其集成到Nuxt3中($fetch)

useAsyncData

根据参考文章修改

<script setup lang="ts">
let data = ref()
  const getData = async () => {
    const { data, pending, error, refresh } = await useAsyncData(
      "mountains",
      () => $fetch("http://localhost:3000/api/csapi")
    );
    console.log('data, pending, error, refresh',data.value, pending.value, error.value, refresh.value);
    
  };
</script><template>
  <div>首页</div>
  <button @click="getData">请求</button>
  <div></div>
</template>
<style lang="scss"></style>
  • data: 传入的异步函数的结果。
  • pending: 一个布尔值,指示数据是否仍在获取中。
  • refresh/execute: 一个函数,可用于刷新 handler 函数返回的数据。
  • error: 如果数据获取失败,则为一个错误对象。
  • status: 一个字符串,指示数据请求的状态 ("idle", "pending", "success", "error")

datapendingstatuserror 是 Vue 引用,它们应该在 <script setup> 中使用时使用 .value 访问,而 refresh/execute 是用于重新获取数据的普通函数。

useAsyncData · Nuxt 可组合函数 - Nuxt 中文 (nuxtjs.org.cn)

useFetch

此可组合项提供了一个围绕 useAsyncData$fetch 的便捷包装器。它会根据 URL 和获取选项自动生成一个键,为基于服务器路由的请求 URL 提供类型提示,并推断 API 响应类型。

useFetch 是一个可组合项,旨在直接在 setup 函数、插件或路由中间件中调用。它返回响应式可组合项,并处理将响应添加到 Nuxt 负载中,以便在页面水合时,可以将它们从服务器传递到客户端,而无需在客户端重新获取数据。

useFetch · Nuxt 可组合函数 - Nuxt 中文 (nuxtjs.org.cn)

总结

由于是初步学习, 就先简单试一下,参考文章中的封装看着挺不错,后面再具体研究

打包部署

既然我们需要使用nuxtjs做项目,那么就需要让用户使用,需要打包部署到服务器才行

执行命令

npm run build

会得到文件夹.output,将文件夹.output放到服务器中

在服务器中安装nodejs和pm2

使用pm2启动pm2 server/index.mjs文件就可以了

我在本地使用的是nodemon启动的

image-20240919152545162

具体的可以参考文章 Nuxt3 项目部署在 Ubuntu 服务器(Node 服务 + pm2 + Nginx 反向代理) (jsnoteclub.com)

其他

查看nuxt官网中集成模块有很多插件可以集成,说明nuxt的社区还是挺好的