最全面Nuxt3项目实战系列

3,690 阅读21分钟

1. 背景

Nuxt.js是一个基于Vue.js的大型应用程序框架,旨在帮助开发者构建快速、可扩展和易于维护的应用程序。然而,随着Vue.js的快速发展和市场需求的不断演变,Nuxt.js也在不断发展和改进。

Nuxt3框架作为Nuxt.js的最新版本,是基于Vue 3和Vite构建的,充分利用了Vue 3的强大功能和Vite的高性能特点。它是一个全新的框架,旨在提供更好的开发体验和更高的性能。

2. 特点

2.1 Vue 3支持

Nuxt3框架的一个重要特点是它完全支持Vue 3。Vue 3是Vue.js的一个主要版本,带来了许多重要的改进和新增功能,如Composition API、更好的性能和更小的包体积。通过与Vue 3的紧密集成,Nuxt3能够更好地利用和发挥Vue 3的优势,提供更好的开发体验和更高的性能。

2.2 Vite集成

Nuxt3框架采用了Vite作为默认的构建工具,Vite是一个基于ESM的构建工具,具有极快的冷启动、快速的热重载和即时更新的能力。通过与Vite的集成,Nuxt3能够更好地利用Vite的高性能特点,加速开发过程,并提供更好的开发体验。

2.3 更灵活的配置

Nuxt3框架引入了更灵活的配置方式,通过采用现代化的配置语法,开发者可以更方便地进行个性化的配置和定制。此外,Nuxt3还提供了更多的配置选项,可以更好地满足不同项目的需求,使开发者能够更轻松地构建各种类型的应用程序。

2.4 更好的性能

Nuxt3框架通过结合Vue 3和Vite的优势,提供了更高的性能。Vue 3带来了更好的响应速度和更小的包体积,而Vite的快速冷启动和热重载能力能够极大地提高开发效率。因此,使用Nuxt3框架可以使应用程序加载更快、响应更快,提供更好的用户体验。

2.5 支持多模式

支持不同的渲染模式,包括CSR、SSG和SSR,可以根据需求选择合适的模式。

Nuxt它实现服务器端渲染(SSR,Server-Side Rendering)和客户端渲染(CSR,Client-Side Rendering)的结合,即同构渲染。

Nuxt是什么?

为了理解什么是Nuxt,我们需要了解为了创建一个现代应用程序我们需要什么:

  • JavaScript frameworkJavaScript框架带来了反应性和web组件,我们选择Vue.js。
  • Webpack and Vite一个在开发中支持热模块替换和在生产中捆绑您的代码的捆绑器,我们同时支持webpack 5Vite
  • Latest JavaScript syntax一个编译器可以在支持旧浏览器的同时编写最新的JavaScript语法,我们使用esbuild
  • Server side一个在开发中为你的应用服务的服务器,但也支持服务器端渲染或API路由,Nuxt使用h3部署的多功能性,如无服务器,工作者,Node.js和无与伦比的性能。
  • Routing library处理客户端导航的路由库,我们选择 vue-router.

这只是冰山一角,想象一下必须为你的项目设置所有这些,让它工作,然后,随着时间的推移维护它。自2016年10月以来,我们一直在这样做,调优所有配置,为任何Vue应用程序提供最佳的优化和性能。

Nuxt处理了这一点,并提供了前端和后端功能,因此您可以专注于重要的事情:创建您的web应用程序。

视图引擎

Nuxt使用Vue.js作为视图引擎。所有Vue 3的功能都可以在Nuxt中使用。你可以在关键概念部分中阅读关于Vue与Nuxt集成的细节。

自动化和约定

Nuxt使用约定和明确的目录结构来自动化重复的任务,并允许开发人员专注于推送特性。配置文件仍然可以自定义和覆盖其默认行为。

  • 自动导入 — 文件系统路由和API层
  • 数据获取工具
  • 零配置TypeScript支持
  • 配置构建工具

更多信息请参见关键概念部分.

渲染模式

Nuxt提供了不同的渲染模式来适应不同的用例:

  • 通用渲染(服务器端渲染和水化)
  • 客户端渲染
  • 完整的静态站点生成
  • 混合渲染(每路由缓存策略)

阅读更多关于Nuxt渲染模式.

服务器引擎

Nuxt服务器引擎Nitro解锁新的全栈功能。

在开发中,它使用Rollup和Node.js工作者进行服务器代码和上下文隔离。它还通过读取server/API/中的文件和从server/middleware/中的服务器中间件生成服务器API。

在生产中,Nitro将你的应用和服务器构建为一个通用的.output目录。这个输出很轻:从任何Node.js模块(除了polyfills)中删除。你可以在任何支持JavaScript的系统上部署这个输出,从Node.js, less server, Workers, Edge-side渲染或纯静态。

阅读更多关于Nuxt服务器引擎.

生产就绪

Nuxt应用程序可以部署在Node或Deno服务器上,预呈现为托管在静态环境中,或者部署到无服务器和边缘提供程序。

更多信息请参见部署部分.

模块化

模块系统允许通过自定义特性和与第三方服务的集成来扩展Nuxt。

发现关于模块的更多信息。

架构

Nuxt由不同的 core packages组成:

Nuxt.js 3.7 正式发布!

nuxt3官网网址:nuxt.com/

nuxt3中文网址:nuxt.com.cn/

8 月 25 日,Nuxt.js 3.7 正式发布!该版本带来了全新的 CLI,原生Web流和响应,渲染优化,异步上下文支持等许多新功能,

下面是一些更新引用:前端充电宝

全新 CLI

Nuxt.js 团队使用 unjs/citty [1] 重构了nuxi,并将其作为独立的存储库,作为第一个依赖于新版本的Nuxt发布。"Nuxi"现在已经与主要的 Nuxt 版本解耦,计划在未来迭代和更快地发布"Nuxi",可以期待很快会有新的功能推出!

Nuxt.js 团队致力于开发一个新的、简约的 CLI 实现,代号为“nuxi”,与 Nuxt 3 一起发布。该项目旨在与 Nuxt 并行地继续进行 CLI 开发和增强,主要是为了实现新目标:

  • 全局访问:可以从任何地方立即访问Nuxt CLI命令,用于启动、初始化、开发、扩展构建和部署Nuxt项目。
  • 模块化架构:使用新的"citty"框架,可以将CLI子命令和功能从不同的源组合起来,提供可扩展性和自定义能力。
  • 自动化操作:可以通过简洁的命令一键完成项目的启动、模块或依赖的添加、Nuxt的升级、配置的修改和模板的创建。
  • 优雅的界面:通过更好的核心集成,提供了更加信息丰富和漂亮的CLI界面。
  • 可编程接口:通过公开的程序化API接口,可以使用开发工具和Web浏览器与CLI进行交互。
  • 快速开发:具备独立版本控制和自我升级支持,可以快速交付更新和实现新的想法。

原生 Web 流和 Response

随着 unjs/h3 [2] 和 unjs/nitro [3] 的改进,现在可以直接从服务端路由返回Response对象,这意味着也可以在 Nuxt 中返回和处理流。

HTML渲染优化

在这个版本中,在从服务端渲染HTML响应方面进行了一些改进。现在,我们会在构建时确定预加载/预获取资源的方式(可以在build:manifest钩子中自定义这一设置)。可以直接在unhead中管理了它们的HTML渲染,这意味着可以配置、、

可以通过experimental.headNext标志来选择即将推出的头部改进。目前,它包括基于capo.js的新排序算法,并允许在未来发布的unhead中启用更多的优化。

export default defineNuxtConfig({
  experimental: {
    headNext: true
  }
})

构建环境快捷方式

在 Nuxt 配置中,现在可以使用 clientclient 和 server 快捷方式来轻松定义特定于 Vite 客户端/服务端或 Webpack 客户端/服务端构建的特定配置。以前这只能通过 vite:extendConfig 和 webpack:config 钩子实现。

例如:

Vite 4.4 支持

Nuxt.js 团队决定取消对 Vite 的次要版本限制,这意味着无论 Vite 何时发布新的功能版本,都可以立即选择使用。Vite 4.4 带来了许多令人兴奋的新功能,包括实验性的 Lightning CSS 支持等!

TypeScript 更新

现在在生成的tsconfig.json中使用纯相对路径,而不是设置baseUrl。这意味着在开发环境(如Docker镜像)中,当绝对路径可能与 IDE 不匹配时,会有更好的支持。

此版本还设置了一些额外的编译器标志默认值,以符合 Vite/TS 的建议。

此外,现在可以在setPageLayout和中获得类型提示的访问权限了。

Async Context 支持

如果你曾经遇到过"Nuxt context unavailable"的问题,那么这个更新可能对你有所帮助。现在在 Nuxt 和 Nitro 中都支持原生的异步上下文,在 Bun 和 Node 环境中可以使用实验性标志进行开启。

这使得在服务端可以使用 Nuxt 组合式函数,而无需确保它们直接在setup函数中被调用。在 Nitro 中也可以实现相同的功能,通过一个新的useEvent()实用工具在服务端路由中使用。

要尝试它,需要启用experimental.asyncContext标志:

Watcher 更新

此版本修复了 watcher 的一些问题,这意味着开发者应该不需要经常重启服务,并且如果使用图层,应该会看到显著的性能提升。

Nitro 2.6

Nitro 2.6 带来了许多令人兴奋的功能,包括更小、更轻的服务器和新的持久数据存储在 .data 目录中。

Nuxt2.x升级3.x

请移步官方迁移指南:nuxt.com.cn/docs/gettin…

以下为Nuxt2.x开发某大型石油项目案例

项目详细可参见:www.yuque.com/donsoft/qkn…

上线网站: sh.jbestore.com/jingbo-b2b-…

下载和安装Nuxt3

依赖环境

  • Node.js v16.11.0+open in new window
  • 某些原因本项目使用Node版本为18.17.0为后续兼容依赖可视化(depcruise)
  • 此项目在 win10 环境下创建
  • 某些约束,本项目仅限使用npm 管理
  • 编辑器vscode

创建项目

  • 步骤 1: 打开一个终端,并使用以下命令创建一个新的启动项目:
npx nuxi@latest init my_nuxt_app
  • 步骤 2: 中打开my_nuxt_app文件夹:
cd my_nuxt_app
  • 步骤 3: 安装依赖项:
  • yarn
npm  install

本地启动

npm run dev

浏览器窗口将自动打开 http://localhost:3000 ; 默认为300端口,

修改端口号

// nuxt.config.ts
 devServer: {
    port: 4098,
  },

安装和使用Element Plus组件库

启动了一个项目,接下来我们为了快速编写我们的网站界面,需要引入UI组件库,我们这里选择Element-plus,接下来我们安装并使用它。

安装组件库:

  • 步骤 1: 在终端中进入项目文件夹:
cd my_nuxt_app
  • 步骤 2: 执行安装命令:
npm i  element-plus
  • 步骤 3: 安装用于用于Nuxt的Element 图标模块及按需引入
  • Element Plus 现在提供一个 nuxt 模块 用于在 Nuxt3 中按需导入组件、指令、样式、图标、函数。
npm i  @element-plus/nuxt -D
npm install @element-plus/icons-vue
  • 步骤 4: 将下面的代码写入你的配置文件:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@element-plus/nuxt'],
  css: [
    'element-plus/dist/index.css',
  ],
})

#使用

<template>
  <el-button @click="ElMessage('hello')">button</el-button>
  <ElButton :icon="ElIconEditPen" type="success">button</ElButton>
  <LazyElButton type="warning">lazy button</LazyElButton>
</template>

上述代码并没有导入组件也没有引入样式,也没安装图标模块,可是却正确显示了我们需要的效果。这些都是Nuxt的Element Plus模块帮我们完成的:

  • 根据需要自动导入组件和样式。
  • 根据需要自动导入指令和样式。
  • 自动从@element-plus/icons-vue导入图标。
  • 自动导入ElMessage、ElNotification等方法。

注意事项

  1. el-button 和 ElButton 两种写法等效。
  2. 在组件名称前增加 Lazy 将惰性加载组件。
  3. 无需手动从 element-plus 中导入组件、指令等内容。如果手动导入,将影响样式的自动导入。
  4. 为了避免图标名称和组件冲突,图标默认前缀值是 ElIcon,你可以通过配置修改它。
  5. 默认只有 ElLoading、ElMessage、ElMessageBox、ElNotification 函数会自动导入,你可以在配置中增加需要自动导入的函数。

效果展示

默认情况下,Nuxt被配置为涵盖大多数用例。nuxt.config.ts文件可以覆盖或扩展这个默认配置。

Nuxt 配置

nuxt.config.ts文件位于Nuxt项目的根目录下,可以覆盖或扩展应用程序的行为。

最小配置文件导出defineNuxtConfig函数,其中包含您的配置对象。defineNuxtConfig助手是全局可用的,无需导入。

nuxt.config.ts

export default defineNuxtConfig({
  // My Nuxt config
})

文档中经常会提到这个文件,例如添加自定义脚本、注册模块或更改呈现模式。

每个配置选项在配置参考.中有描述

你不必使用TypeScript来构建Nuxt的应用程序。但是,强烈建议使用.ts作为nuxt.config 文件的扩展名。通过这种方式,您可以从IDE中的提示中受益,以避免在编辑配置时出现错别字和错误。

环境变量和私有令牌

runtimeConfig API向应用程序的其余部分公开了诸如环境变量之类的值。默认情况下,这些键只在服务器端可用。runtimeConfig.public中的键也可以在客户端使用。

这些值应该在nuxt.config 中定义,并且可以使用环境变量重写。

nuxt.config.ts

export default defineNuxtConfig({
  runtimeConfig: {
  
    apiSecret: '123',
  
   public: {
      baseUrl: process.env.NUXT_PUBLIC_API_BASE,
    },
  }
})

这些变量使用useRuntimeConfig组合变量向应用程序的其余部分公开。

pages/index.vue

<script setup>
const { baseURL: apiBase } = useRuntimeConfig().public;
</script>

runtimeConfigvsapp.config

如上所述,runtimeConfig和app.config 都是用来向应用程序的其他部分公开变量的。为了决定你是应该使用其中一种还是另一种,这里有一些指导方针:

  • runtimeConfig:需要在使用环境变量构建后指定的私有或公共令牌。
  • app.config:在构建时确定的公共令牌,网站配置,如主题变量,标题和任何不敏感的项目配置。
功能runtimeConfigapp.config
客户端HydratedBundled
环境变量✅ Yes❌ No
Reactive✅ Yes✅ Yes
类型支持✅ Partial✅ Yes
每个请求的配置❌ No✅ Yes
模块热更新❌ No✅ Yes
非原始JS类型❌ No✅ Yes

External Configuration Files

Nuxt使用 nuxt.config.ts的文件作为配置的单一信任源,并跳过读取外部 配置文件。在构建项目的过程中,您可能需要配置它们。以下表突出显示了常用配置,以及在适用的情况下如何使用Nuxt配置它们。

NameConfig FileHow To Configure
Nitronitro.config.tsUse nitrokey in nuxt.config
PostCSSpostcss.config.jsUse postcsskey in nuxt.config

下面是其他常见配置文件的列表:

NameConfig FileHow To Configure
TypeScripttsconfig.jsonMore Info
ESLint.eslintrc.jsMore Info
Prettier.prettierrc.jsonMore Info
Stylelint.stylelintrc.jsonMore Info
commitLintcommitlint.config.jsMore Info

关于eslint + prettier + husky + commitlint 组合配置

vscode 扩展中搜索FE Tools 回车安装

项目局部配置:

选中项目根目录,右键选择 前端代码规范一键配置

根据项目架构依次选择,Reat,Javascript, npm ; 点击一键配置

更多详细请前往:juejin.cn/post/723923…

FE-Tools插件集成在vscode 中 ,关于代码静态检查执行,安装简单方便,不需要繁琐的配置

如果你想学习,也可以手动搭建

安装eslint

npm i eslint eslint-plugin-vue --save-devpnpm 
npm install @typescript-eslint/parser --save-dev
npm install @typescript-eslint/eslint-plugin --save-dev
/*
 * @Author: lzx
 * @Date: 2023-10-18 08:55:27
 * @LastEditors:lzxaily1107 493535562@qq.com
 * @LastEditTime: 2023-10-18 09:47:03
 * @FilePath: \nuxt-web-pc.eslintrc.js
 * @Description: eslint配置
 */
module.exports = {
  parser: "vue-eslint-parser",

  parserOptions: {
    parser: "@typescript-eslint/parser",
    ecmaVersion: 2020,
    sourceType: "module",
    ecmaFeatures: {
      jsx: true,
    },
  },

  extends: [
    "plugin:vue/vue3-recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier",
    "plugin:prettier/recommended",
  ],

  rules: {
    "@typescript-eslint/ban-ts-ignore": "off",
    "@typescript-eslint/explicit-function-return-type": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-var-requires": "off",
    "@typescript-eslint/no-empty-function": "off",
    "vue/custom-event-name-casing": "off",
    "no-use-before-define": "off",
    "@typescript-eslint/no-use-before-define": "off",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        argsIgnorePattern: "^h$",
        varsIgnorePattern: "^h$",
      },
    ],
    "no-unused-vars": [
      "error",
      {
        argsIgnorePattern: "^h$",
        varsIgnorePattern: "^h$",
      },
    ],
    "space-before-function-paren": "off",
    quotes: ["error", "single"],
    "comma-dangle": ["error", "never"],
    quotes: "off",
    "comma-dangle": "off",
    "vue/multi-word-component-names": "off", //关闭多词名称校验
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": "off",
  },
};

package.json文件配置eslint

  "scripts": {
    "build": "nuxt build",
    "dev": "npm run check && nuxt dev --dotenv .env.local",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare",
    "eslint:comment": "使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件",
    "eslint": "eslint --ext .js,.ts,.tsx,.vue --ignore-path .gitignore --fix src",
    "prettier:comment": "自动格式化当前目录下的所有文件",
    "prettier": "prettier .  --write",
    "commit:comment": "引导设置规范化的提交信息",
    "commit": "git-cz",
    "check": "npx depcruise src --config .dependency-cruiser.js",
    "preinstall": "only-allow npm"
  },

执行npm run eslint 可查看效果

安装prettier & commitLint

npm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev

npm install -D commitizen cz-conventional-changelog @commitlint/config-conventional @commitlint/cli commitlint-config-cz cz-customizable

安装Husky

# 1.安装
pnpm i husky lint-staged -D

# 2.生成 .husky 的文件夹
npx husky install

# 3.添加 hooks,会在 .husky 目录下生成一个 pre-commit 脚本文件
npx husky add .husky/pre-commit "npx --no-install lint-staged"

# 4.添加 commit-msg
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

这里更多配配置项在后面统一在见项目,这里不在书写配置

页面开发

安装css扩展语言-Less

安装

  • ya
npm install Less -D

配置

  vite: {
    css: {
      preprocessorOptions: {
        less: {
          additionalData: '@import "@/assets/css/main.less";', //全局配置
        },
      },
      //    postcss: {
      //      plugins: [
      //        require('autoprefixer'),
      //        require('postcss-px-to-viewport-8-plugin')({
      //          viewportWidth: 1980,     // 视窗的宽度,对应设计稿的宽度
      //          viewportHeight: 5000,    // 视窗的高度,对应设计稿的高度
      //          unitPrecision: 3,       // 指定`px`转换为视窗单位值的小数位数
      //          viewportUnit: 'vw',     // 指定需要转换成的视窗单位,建议使用vw
      //          fontViewportUnit: 'rem',
      //          propList: ['*', '!font-size', '!line-height'],
      //          selectorBlackList: [],   //指定不转换为视窗单位的CSS选择器
      //          minPixelValue: 1,       // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
      //          mediaQuery: false       // 媒体查询里的单位是否需要转换单位
      //        }),
      //        require('postcss-pxtorem')({
      //          rootValue: 100,
      //          propWhiteList: [],
      // // selectorBlackList: [ //排除一下选择器
      // //   '.el-*',  // element-plus 选择器
      // //   '.fixed',
      // //   '.border-1px',
      // //   '.animated'
      // // ]

      //        })
      //      ]

      //    },
    },
  },

默认在assets/css/main.less为主入口

使用

<style lang="less" scoped>
// ...
</style>

公共部分(头部、底部)编写

大多数组件是用户界面的可重用部分,如果你的项目比较单一,统一使用app.vue文件即可,

但大多数情况项目都会有不同的Layout来展示统一布局

  • 第一步 我们先创建头部和底部组件:
# 创建组件目录
components

# 创建公用的头部和底部组件
components/MainHeader.vue 
components/MainFooter.vue

# 创建公用布局页面
layouts/default.vue
  • 第二步 在app.vue文件中编写
  • layouts/default.vu
<template>
  <!-- <NuxtWelcome /> -->
    <!-- 路由出口 -->
    <NuxtLayout>
      <NuxtPage>
        <NuxtLoadingIndicator />
      </NuxtPage>
    </NuxtLayout>
</template>

此时默认的Layout为default

// 默认default布局
<template>
  <div class="warp">
    <div class="header">
      <main-header />
    </div>
    <div class="main">
     	<slot/>
    </div>
    <div class="footer">
      <main-footer />
    </div>
  </div>
</template>
<script setup></script>
<style lang="less">
</style>

更改布局

直接在具体模块中更改布局名称

<script setup>
definePageMeta({
  layout: "default",
});
</script>

首页编写

<!--
 * @Author: lzx
 * @Date: 2023-10-14 12:08:20
 * @LastEditors: lzxaily1107 493535562@qq.com
 * @LastEditTime: 2023-10-18 13:09:07
 * @FilePath: \vite-nuxt3-app\src\pages\index.vue
 * @Description: 首页
-->

<template>
  <div class="main">
    <p class="title">欢迎来第一个页面</p>
    <P class="tit">测试适配字体</P>
    <!--  <div>{{nickName}}</div> -->
    <!-- <div v-if="userInfo">
      <p>{{ userInfo.data.name }}</p>
      <p>{{ userInfo.data.email }}</p>
	  <img :src=  userInfo.data.avatar />

	</div> -->
    <el-carousel height="500px">
      <el-carousel-item v-for="item in banner" :key="item">
        <img :src="item.url" :alt="item.alt" />
      </el-carousel-item>
    </el-carousel>

	<el-button @click="ElMessage('hello')">button</el-button>
	<ElButton :icon="ElIconEditPen" type="success">button</ElButton>
	<LazyElButton type="warning">lazy button</LazyElButton>
  </div>
</template>
<script setup>
// import { userManager } from "@/stores/userManager";
// import { storeToRefs } from "pinia";
definePageMeta({
  layout: "default",
});
// 从pinia 中获取数据转为响应式
// const store = userManager();
// const { nickName } = storeToRefs(store);

// const userInfo = ref(null)
// 测试从接口获取数据显示在模板中
// const getInfo = async () => {
//     const { apiBase: baseURL } = useRuntimeConfig().public;
//     const { data,error} = await useFetch( baseURL + 'api/users/2', {
//     })
//     console.log('获取返回的数据77',data.value)
//     userInfo.value = data.value
// };
onMounted(() => {
  // getInfo();
});
// 获取cookie的值
const counter = useCookie("username");
console.log("获取缓存的值", counter.value);
// import imgUrl from "~/assets/imgs/banner01.png";
const banner = ref([
  {
    url: '@/assets/imgs/banner01.png',
    alt: "banner01",
  },
]);
</script>

<style lang="less" scoped>
</style>

自动导入

在 Nuxt.js 3 中,自动导入功能主要用于以下几个方面:

自动导入组件:可以将应用中的组件自动导入到模板中,不需要手动导入。

自动导入路由:可以将应用中的路由自动导入到路由配置中,不需要手动配置。

自动导入中间件:可以将应用中的中间件自动导入到路由中间件配置中,不需要手动配置。

SEO 和 Meta

// 基础示例
export default defineNuxtConfig({
  app: {
    head: {
      charset: 'utf-16',
      viewport: 'width=500, initial-scale=1',
      title: 'My App',
      meta: [
        // <meta name="description" content="My amazing site">
        { name: 'description', content: 'My amazing site.' }
      ],
    }
  }
})

可组合函数:useHead

useHead可组合函数允许您以编程和反应式的方式管理head标签,由@vueuse/head提供支持。

与所有可组合组件一样,它只能与组件的setup和生命周期钩子一起使用。

在任意模块中使用

<script setup lang="ts">
useHead({
  title: 'My App',
  meta: [
    { name: 'description', content: 'My amazing site.' }
  ],
  bodyAttrs: {
    class: 'test'
  },
  script: [ { children: 'console.log('Hello world')' } ]
})
</script>

404页面

项目根目录添加error.vue

中间件

配置登录鉴权

数据获取

nuxt3中提供的数据获取函数有以下四个:

  • useFetch
  • useLazyFetch
  • useAsyncData
  • useLazyAsyncData

更多详细说明见官方:nuxt.com.cn/docs/gettin…

这里使用一个开源的api 地址来测试 useFetch的使用。

数据结构为:

首页面编写

<template>
   <div v-if="userInfo">
      <p>{{ userInfo.data.name }}</p>
      <p>{{ userInfo.data.email }}</p>
	     <img :src=  userInfo.data.avatar />

	</div>
</template>
<script setup>
const userInfo = ref(null)
// 测试从接口获取数据显示在模板中
 const getInfo = async () => {
     const { apiBase: baseURL } = useRuntimeConfig().public;
     const { data,error} = await useFetch( baseURL + 'api/users/2', {
     })
     console.log('获取返回的数据77',data.value)
     userInfo.value = data.value
 };

</script>

状态管理

    npm install pinia @pinia/nuxt
    npm i -D @pinia-plugin-persistedstate/nuxt

stores目录下新建store文件

/*
 * @Author: lzx
 * @Date: 2023-10-14 12:08:20
 * @LastEditors: lzxaily1107 493535562@qq.com
 * @LastEditTime: 2023-10-15 18:06:58
 * @FilePath: \vite-nuxt3-app\src\stores\userManager.ts
 * @Description: 状态管理
 */
import { defineStore } from "pinia";
export const userManager = defineStore({
  id: "userId",
  state: () => {
    return {
      nickName: "lzx",
      age: 18,
      userData: {},
    };
  },
  getters: {},

  actions: {
    // 异步
    //  async fetchUser() {
    // 	const response = await axios.get('/api/user')
    // 	this.userData = response.data
    // }
  },
  // 默认储存为sessionStotage
  // persist: true,
  // persist: {
  //  enabled:true,
  //  strategies :[{
  // 	 key: 'userId', // 修改存储的键名,默认为当前 Store 的 id
  // 	 storage: window.localStorage, // 存储位置修改为 localStorage
  // 	 paths:['age'] // 配置需要缓存的数据
  // }]

  // },

  persist: {
    // storage: persistedState.localStorage,
  },
});

首页面中使用store

<template>
   <div>{{nickName}}</div>
</template>
<script setup>
import { userManager } from "@/stores/userManager";
import { storeToRefs } from "pinia";
definePageMeta({
  layout: "default",
});
// 从pinia 中获取数据转为响应式
const store = userManager();
const { nickName } = storeToRefs(store);
</script>

移动端适配

npm install postcss --save-dev
npm install postcss-px-to-viewport --save-dev
npm install postcss-px-to-rem --save-dev
  vite: {
    css: {
      preprocessorOptions: {
        less: {
          additionalData: '@import "@/assets/css/main.less";', //全局配置
        },
      },
      //    postcss: {
      //      plugins: [
      //        require('autoprefixer'),
      //        require('postcss-px-to-viewport-8-plugin')({
      //          viewportWidth: 750,     // 视窗的宽度,对应设计稿的宽度
      //          viewportHeight: 690,    // 视窗的高度,对应设计稿的高度
      //          unitPrecision: 3,       // 指定`px`转换为视窗单位值的小数位数
      //          viewportUnit: 'vw',     // 指定需要转换成的视窗单位,建议使用vw
      //          fontViewportUnit: 'rem',
      //          propList: ['*', '!font-size', '!line-height'],
      //          selectorBlackList: [],   //指定不转换为视窗单位的CSS选择器
      //          minPixelValue: 1,       // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
      //          mediaQuery: false       // 媒体查询里的单位是否需要转换单位
      //        }),
      //        require('postcss-pxtorem')({
      //          rootValue: 100,
      //          propWhiteList: [],
      // // selectorBlackList: [ //排除一下选择器
      // //   '.el-*',  // element-plus 选择器
      // //   '.fixed',
      // //   '.border-1px',
      // //   '.animated'
      // // ]

      //        })
      //      ]

      //    },
    },
  },

工程化配置

借助FE-Tools工具安装

安装动画插件 &代理配置

npm i aos -D
  nitro: {
    // devProxy: {
    //   "/api": {
    //     target: "https://reqres.in",
    //     // changeOrigin: true,
    //     // prependPath: true,
    //   },
    // },
    // routeRules: {
    //   '/api/**': {
    //     proxy: 'http://localhost:3001/**'
    //   }
    // }
  }

  // 动画使用
  <div  data-aos="zoom-out" data-aos-offset="100"  data-aos-easing="ease-in-sine" data-aos-duration="750"></div>

配置依赖可视化及仅限npm 包管理

全局安装depcheck, 用于检测包的使用情况

项目配置仅使用npm 来管理

使用depcruise 来管理依赖可视化

详细见:juejin.cn/post/723843…

安裝 VS Code 插件

推荐安裝下面 VS Code 插件,

Vue Language Features (Volar):

TypeScript Vue Plugin (Volar): Vue 的 TypeScript 插件。

打包部署

细节优化

1. 添加加载进度组件

<template>
  <NuxtLoadingIndicator />
</template>

2. 添加回顶部组件

<template>
  <el-backtop />
</template>

3. ico图标配置

head: {
    link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
}

打包

yarn build
# or
npm run build

部署

安装pm2

此步骤是在服务器上操作, 前提是安装好了Nodejs环境.

npm install pm2@latest -g
配置pm2
  1. 常见配置文
 pm2.config.js
  1. 写入配置项
module.exports = {
  apps: [
    {
      name: 'my_nuxt_app',
      port: '4098',
      exec_mode: 'cluster',
      instances: 'max',
      script: './.output/server/index.mjs'
    }
  ]
}
  • exec_mode:应用程序启动模式,这里设置的是cluster_mode(集群),默认是fork
  • instances:启用多少个实例,可用于负载均衡。如果-i 0或者-i max,则根据当前机器核数确定实例数目。
  • pm2配置参数open in new window
  1. 上传项目文件到服务器
  2. 到服务器项目目录启动
pm2 start pm2.config.js

详细部署见官方:nuxt.com.cn/docs/gettin…

总结:

更多如请求二次封装,全局的userState& userCookie使用等,如对你有帮助请关注、点个赞吧

项目地址:codeup.aliyun.com/6322fc75d4d…

如有需要,请私信加权限