NUXT3学习笔记

news2024/11/19 1:41:38

1.邂逅SPA、SSR

1.1 单页面应用程序

单页应用程序 (SPA) 全称是:Single-page application,SPA应用是在客户端呈现的(术语称:CSR(Client Side Render))

SPA的优点

  1. 只需加载一次
    1. SPA应用程序只需要在第一次请求时加载页面,页面切换不需重新加载,而传统的Web应用程序必须在每次请求时都得加载页面,需要花费更多时间。因此,SPA页面加载速度要比传统 Web 应用程序更快。
  2. 更好的用户体验
    1. SPA 提供类似于桌面或移动应用程序的体验。用户切换页面不必重新加载新页面
    2. 切换页面只是内容发生了变化,页面并没有重新加载,从而使体验变得更加流畅
  3. 可轻松的构建功能丰富的Web应用程序

SPA的缺点

  1. SPA应用默认只返回一个空HTML页面,不利于SEO (search engine optimization )
  2. 首屏加载的资源过大时,一样会影响首屏的渲染
  3. 也不利于构建复杂的项目,复杂 Web 应用程序的大文件可能变得难以维护

1.2 SEO的优化

在这里插入图片描述

1.3 静态站点生成(SSG)

静态站点生成(SSG) 全称是:Static Site Generate,是预先生成好的静态网站

  • SSG 应用一般在构建阶段就确定了网站的内容。
  • 如果网站的内容需要更新了,那必须得重新再次构建和部署
  • 构建 SSG 应用常见的库和框架有: Vue Nuxt、 React Next.js 等

SSG的优点

  • 访问速度非常快,因为每个页面都是在构建阶段就已经提前生成好了。
  • 直接给浏览器返回静态的HTML,也有利于SEO
  • SSG应用依然保留了SPA应用的特性,比如:前端路由、响应式数据、虚拟DOM等

SSG的缺点

  • 页面都是静态,不利于展示实时性的内容,实时性的更适合SSR。
  • 如果站点内容更新了,那必须得重新再次构建和部署

1.4 SSR 服务器端渲染

服务器端渲染全称是:Server Side Render,在服务器端渲染页面,并将渲染好HTML返回给浏览器呈现

SSR应用的页面是在服务端渲染的,用户每请求一个SSR页面都会先在服务端进行渲染,然后将渲染好的页面,返回给浏览器呈现

在这里插入图片描述

优缺点

  • 更快的首屏渲染速度
  • 更好的SDO
  • SSR应用程序在 Hydration 之后依然可以保留 Web 应用程序的交互性。比如:前端路由、响应式数据、虚拟DOM等。

  • SSR 通常需要对服务器进行更多 API 调用,以及在服务器端渲染需要消耗更多的服务器资源,成本高
  • 增加了一定的开发成本,用户需要关心哪些代码是运行在服务器端,哪些代码是运行在浏览器端
  • SSR 配置站点的缓存通常会比SPA站点要复杂一点

1.5 SSR的解决方案

  1. php、jsp…………
  2. 从0搭建SSR项目
  3. 直接使用流行的框架

1.6 跨请求状态污染

在SPA中,整个生命周期中只有一个App对象实例 或 一个Router对象实例 或 一个Store对象实例都是可以的,因为每个用户在使用浏览器访问SPA应用时,应用模块都会重新初始化,这也是一种单例模式

然而,在 SSR 环境下,App应用模块通常只在服务器启动时初始化一次。同一个应用模块会在多个服务器请求之间被复用,而我们的单例状态对象也一样,也会在多个请求之间被复用,比如:当某个用户对共享的单例状态进行修改,那么这个状态可能会意外地泄露给另一个在请求的用户

这种情况称之为跨请求状态污染

  • 可以在每个请求中为整个应用创建一个全新的实例,包括后面的 router 和全局 store等实例。
  • 所以我们在创建App 或 路由 或 Store对象时都是使用一个函数来创建,保证每个请求都会创建一个全新的实例
  • 这样也会有缺点:需要消耗更多的服务器的资源

2.nuxt

2.1 nuxt定义

Nuxt 使用 h3来实现部署可移植性

Nuxt 框架可以用来快速构建下一个 Vue.js 应用程序,如支持 CSR 、SSR、SSG 渲染模式的应用等

特点

  • Nuxt3 是基于 Vue3 + Vue Router + Vite 等技术栈,全程 Vue3+Vite 开发体验(Fast)。
  • 自动导包
    • Nuxt 会自动导入辅助函数、组合 API和 Vue API ,无需手动导入。
    • 基于规范的目录结构,Nuxt 还可以对自己的组件、 插件使用自动导入
  • 约定式路由(目录结构即路由)
    • Nuxt 路由基于vue-router,在 pages/ 目录中创建的每个页面,都会根据目录结构和文件名来自动生成路由
  • 渲染模式:Nuxt 支持多种渲染模式(SSR、CSR、SSG等)
    • 通用渲染(服务器端渲染和水合)
    • 仅客户端渲染
    • 全静态站点生成
    • 混合渲染(每条路由缓存策略)
  • 利于搜索引擎优化:服务器端渲染模式,不但可以提高首屏渲染速度,还利于SEO
  • 服务器引擎
    • 在开发环境中,它使用 Rollup 和 Node.js
    • 在生产环境中,使用 Nitro 将您的应用程序和服务器构建到一个通用.output目录中
    • Nitro服务引擎提供了跨平台部署的支持,包括 Node、Deno、Serverless、Workers等平台上部署

在这里插入图片描述

2.2 环境搭建

命令行

  1. npx nuxi init hello-nuxt
  2. pnpm dlx nuxi init hello-nuxt
  3. npm install –g nuxi && nuxi init hello-nuxt

pnpm install --shamefully-hoist(创建一个扁平的 node_modules 目录结构,类似npm 和 yarn)

或者创建一个 .npmrc 文件,里面写入 shamefully-hoist=true

2.3 安装nuxt报错

在这里插入图片描述

  1. 配置hosts

    1. Mac电脑:/etc/hosts
    2. win电脑:c:/Windows/System32/drivers/etc/hosts
  2. 拖动到vscode里面去,追加下面这行

    185.199.108.133 raw.githubusercontent.com
    
  3. 保存(以管理员身份覆盖)

在这里插入图片描述

185.199.108.133 raw.githubusercontent.com

2.4 package.json script

  • "build": "nuxt build":用于构建 Nuxt.js 应用程序。构建的过程中,Nuxt.js 会生成静态文件和服务器代码。
  • "dev": "nuxt dev":用于在本地开发环境中启动 Nuxt.js 应用程序。该命令会启动一个本地服务器,并监听文件更改,以便在保存文件时自动重新加载您的应用程序。
  • "generate": "nuxt generate":用于生成静态网站。该命令将预渲染所有页面,并生成一组静态 HTML 文件和关联的 JS 和 CSS 文件。这些文件可以部署到任何支持静态文件的 Web 服务器上。
  • "preview": "nuxt preview":用于在本地启动预览服务器,预览静态生成的应用程序。预览服务器支持实时重载,并提供与生产环境相同的功能。您可以使用该命令来测试静态生成的应用程序,并查看实际生成的结果。
  • "postinstall": "nuxt prepare":用于安装依赖项和设置应用程序。在应用程序安装时,该命令将安装所有必需的依赖项,并运行一些必要的设置步骤,以确保应用程序可以正常工作。会生成 .nuxt 目录

注意 postinstall 是 npm 的脚本钩子

  • prepublishOnly: 在使用 npm publish 发布包之前运行。如果脚本返回非零状态,则发布流程将被取消。
  • prepare: 在包安装时运行,以及在本地开发环境中运行 npm linknpm install 时运行。
  • prepublish: 在使用 npm publish 发布包之前运行。该脚本也会在 npm pack 打包时运行。
  • preinstall: 在包安装时运行,但在包下载之前运行。如果脚本返回非零状态,则安装流程将被取消。
  • postinstall: 在包安装后运行。通常用于安装依赖项并进行构建、编译或其他设置。
  • preuninstall: 在包卸载之前运行。如果脚本返回非零状态,则卸载流程将被取消。
  • postuninstall: 在包卸载后运行。通常用于清理文件或数据。
  • preversion: 在运行 npm version 之前运行。如果脚本返回非零状态,则 npm version 流程将被取消。
  • version: 在运行 npm version 之后运行。通常用于在版本控制中更新文件或提交更改。
  • postversion: 在运行 npm version 之后运行。通常用于向 Git 或其他存储库提交版本标记。
  • pretest: 在运行 npm test 之前运行。如果脚本返回非零状态,则 npm test 流程将被取消。
  • test: 运行 npm test 命令时运行。
  • posttest: 在运行 npm test 之后运行。
  • prestart: 在运行 npm start 之前运行。如果脚本返回非零状态,则 npm start 流程将被取消。
  • start: 运行 npm start 命令时运行。
  • poststart: 在运行 npm start 之后运行。
  • prestop: 在运行 npm stop 之前运行。如果脚本返回非零状态,则 npm stop 流程将被取消。
  • stop: 运行 npm stop 命令时运行。
  • poststop: 在运行 npm stop 之后运行。

2.5 目录结构

在这里插入图片描述

2.6 nuxt.config

nuxt.config.ts 配置文件位于项目的根目录,可对Nuxt进行自定义配置。比如,可以进行如下配置:

  • runtimeConfig:运行时配置,即定义环境变量
    • 可通过.env文件中的环境变量来覆盖,优先级(.env > runtimeConfig)
    • .env的变量会打入到process.env中,符合规则的会覆盖runtimeConfig的变量
    • .env一般用于某些终端启动应用时动态指定配置,同时支持dev和pro
  • appConfig: 应用配置,定义在构建时确定的公共变量,如:theme
    • 配置会和 app.config.ts 的配置合并(优先级 app.config.ts > appConfig)
  • app:app配置
    • head:给每个页面上设置head信息,也支持 useHead 配置和内置组件
  • ssr:指定应用渲染模式
  • router:配置路由相关的信息,比如在客户端渲染可以配置hash路由
  • alias:路径的别名,默认已配好
  • modules:配置Nuxt扩展的模块,比如:@pinia/nuxt @nuxt/image
  • routeRules:定义路由规则,可更改路由的渲染模式或分配基于路由缓存策略(公测阶段)
  • builder:可指定用 vite 还是 webpack来构建应用,默认是vite。如切换为 webpack 还需要安装额外的依赖

2.6.1 runtimeConfig

export default defineNuxtConfig({
  devtools: { enabled: true },
  runtimeConfig: {
    // 放在 public的 keyvalue 可以在服务端访问,也可以在客户端访问
    // 没有放在 public 和app  里面的只能在服务端访问
    // 放在 app 的keyvalue 可以在 服务端访问,也可以在客户端访问

    // 运行时的配置
    appKey: "appKey",

    public: {
      baseUrl: "www.baidu.com",
    },
    app: {
      name: "app",
    },
  },
});
# NUXT_ 开头
# 这里的环境变量会自动注入到 process.env 里面去(但是并不是有提示,在服务端能打印出来,在客户端不行)
# 这里定义的 如果和 runtimeConfig 重名,会进行覆盖(前提是 NUXT 开头)
NUXT_APP_KEY=env里面定义
NUXT_PUBLIC_AUTHOR=呆呆狗
AGE=30
NUXT_APP_KEY_AGE=40

env 文件的环境变量,可以在服务端用 process.env.xxxx 打印出来,但是客户端不行

const runtimeConfig = useRuntimeConfig();
console.log(
  "runtimeConfig",
  runtimeConfig,
  process.env.NUXT_APP_KEY,
  process.env.AGE
);
// console.log("process", process, process.env.NUXT_APP_KEY_AGE);

// 在客户端,process 包含了下面这些
// {
//     "dev": true,
//     "test": false,
//     "env": {
//         "NODE_ENV": "development"
//     },
//     "server": false,
//     "client": true,
//     "browser": true,
//     "nitro": false,
//     "prerender": false
// }

// console.log("runtimeConfig", runtimeConfig);

// if (process.server) {
//   console.log("运行在 server");
//   console.log(runtimeConfig.appKey, "runtimeConfig.appKey");
// }
// if (process.client) {
//   console.log("运行在 client");
//   console.log(runtimeConfig.appKey, "runtimeConfig.appKey"); // undefined
// }

2.6.2 app.config

Nuxt 3 提供了一个 app.config.ts 应用配置文件,用来定义在构建时确定的公共变量.比如:网站的标题、主题色 以及任何不敏感的项目配置

app.config.ts 配置文件中的选项不能使用env环境变量来覆盖,与 runtimeConfig 不同

不要将秘密或敏感信息放在 app.config.ts 文件中,该文件是客户端公开

// nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  // 定义应用的配置
  // 在客户端和服务端都可以用
  appConfig: {
    title: "nuxt.config.ts  呆呆狗测试 nuxt3",
  },
});


// app.vue
let appConfig = useAppConfig();
console.log("appConfig", appConfig.title, appConfig.age); // appConfig 我是单独的文件配置的 我是单独文件配置的age

// app.config.ts
export default defineAppConfig({
  // 这里的优先级,大于 nuxt.config.js 中的配置
  title: "我是单独的文件配置的",
  age: "我是单独文件配置的age",
});

2.6.3 runtimeConfig 与 app.config 对比

runtimeConfig 和 app.config都用于向应用程序公开变量。要确定是否应该使用其中一种,以下是一些指导原则

runtimeConfig:定义环境变量,比如:运行时需要指定的私有或公共token

app.config:定义公共变量,比如:在构建时确定的公共token、网站配置

在这里插入图片描述

app.config 是不能再运行时更改的,而runtimeConfig 是可以改

2.6.4 SEO

  1. 在 nuxt.config.ts 中配置
  2. 在vue 文件中使用 useHead 函数
  3. 在vue文件 template 使用SEO 内置组件
// nuxt.config.ts
export default defineNuxtConfig({
  devtools: { enabled: true },
  // app 属性
  app: {
    head: {
      title: "呆呆狗网站",
      charset: "UFT-8",
      meta: [
        { name: "keywords", content: "关键词1 关键词2" },
        { name: "description", content: "这是一个网站,描述" },
      ],
      style: [
        {
          children: `body{ color: red; }`,
        },
      ],
      script: [
        {
          src: "http://daidaigou.com",
        },
        {
          src: "http://daidaigoubody.com",
        },
      ],
    },
  },
});

useHead({
  script: [{ src: "www.daidaigou.com", body: true }],
});
<template>
  <div>
    <h2>测试</h2>
    <Meta name="description" content="我是在template 里面添加的"></Meta>
    <Style type="text/css" children="body { background-color: green; }"></Style>
    <!-- <NuxtWelcome /> -->
  </div>
</template>

2.6.5 样式

  1. vue 文件中 创建 style 标签书写
  2. 在 nuxt.config.ts 引入全局样式文件
  3. 在 assets 创建 css /scss(如果用scss需要安装一下 npm i sass) ,在vue 文件中引入也是可以的
<style scoped lang="scss">
	@important "~/assets/styles/variables.scss";
  /*
  也可以这样导入,这样导入可以起一个别名,如果起了别名用的时候就是, abc.xxx,就是加了一个命名空间
  as * 可以省略命名空间
  @use '~/assets/styles/variables.scss' as abc
	@use '~/assets/styles/variables.scss' as *
  */
</style>
export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "@/assets/_colors.scss" as *;'
        }
      }
    }
  }
})
// 给 SCSS 模块自动添加这个 样式文件

2.6.6 资源的导入

<template>
  <div>
    <h2 class="global_title">路由 首页</h2>
    <img src="~/assets/images/user.png" alt="" />
    <div class="bg"></div>
    <img :src="bgImg" alt="" />
  </div>
</template>

<script setup lang="ts">
import bgImg from "@/assets/images/feel.png";
</script>

<style scoped>
.bg {
  width: 200px;
  height: 200px;
  background-image: url(assets/images/feel.png);
}
</style>

2.6.7 界面的创建

  • Nuxt项目中的页面是在 pages目录 下创建的
  • 在pages目录创建的页面,Nuxt会根据该页面的目录结构和其文件名来自动生成对应的路由。
  • 页面路由也称为文件系统路由器(file system router),路由是Nuxt的核心功能之一

新建界面步骤

  1. 创建页面文件,比如: pages/index.vue
  2. 将< NuxtPage /> 内置组件添加到 app.vue
  3. 页面如果使用scss那么需要安装:npm i sass -D

命令快速创建界面

  1. npx nuxi add page home # 创建home页面
  2. npx nuxi add page detail/[id] # 创建detail页面
  3. npx nuxi add page user-[role]/[id] # 创建user页面
  4. npx nuxi add page login/index.vue 创建login 目录

2.6.8 组件导航

< NuxtLink>是Nuxt内置组件,是对 RouterLink 的封装,用来实现页面的导航

该组件底层是一个 < a >标签,因此使用 a + href 属性也支持路由导航

但是用a标签导航会有触发浏览器默认刷新事件,而 NuxtLink 不会,NuxtLink还扩展了其它的属性和功能

应用Hydration后(已激活,可交互),页面导航会通过前端路由来实现。这可以防止整页刷新

具体参考 官网

2.6.9 编程导航

Nuxt3除了可以通过< NuxtLink>内置组件来实现导航,同时也支持编程导航:navigateTo

navigateTo 函数在服务器端和客户端都可用,也可以在插件、中间件中使用,也可以直接调用以执行页面导航,

navigateTo( to , options)
to: 可以是纯字符串 或 外部URL 或 路由对象,
options: 导航配置,可选
	replace:默认为false,为true时会替换当前路由页面
	external:默认为false,不允许导航到外部连接,true则允许
	等一些其他
	
navigateTo 返回值是一个promise

仍然可以继续使用vue-router 的语法,但是建议使用 navigateTo 进行跳转

2.6.10 动态路由

动态路由也是根据目录结构和文件的名称自动生成

  • pages/detail/[id].vue -> /detail/:id

  • pages/detail/user-[id].vue -> /detail/user-:id

  • pages/detail/[role]/[id].vue -> /detail/:role/:id

  • pages/detail-[role]/[id].vue -> /detail-:role/:id

动态路由 和 index.vue 能同时存在, Next.js则可以

2.6.11 404

通过在方括号内添加三个点 ,如:[…slug].vue 语法,其中slug可以是其它字符串

除了支持在 pages根目录下创建,也支持在其子目录中创建

2.6.12 嵌套路由

  1. 创建一个一级路由,如:parent.vue,在page 根目录下
  2. 创建一个与一级路由同名同级的文件夹,如: parent
  3. 在parent文件夹下,创建一个嵌套的二级路由
    1. 如:parent/child.vue, 则为一个二级路由页面
    2. 如: parent/index.vue 则为二级路由默认的页面
  4. 需要在parent.vue中添加 NuxtPage 路由占位

2.6.13 中间件

执行的顺序是

  1. 全局中间件
  2. 界面自身中间件

2.6.14 路由验证

<template>
  <div>
    用户
    {{ $route.params.id }}
  </div>
</template>

<script lang="ts" setup>
definePageMeta({
  validate: async (route) => {
    console.log("进行验证~~~~");

    // return /^\d+$/.test(route.params.id as string);
    // return true;   // true 成功
    return {
      // 如果返回对象,那也是验证失败 
      statusCode: 301,
      statusMessage: "界面加载失败~",
    };
  },
});
</script>

<style scoped></style>

路由验证失败,可以自定义错误页面

在项目根目录(不是pages目录)新建 error.vue

<template>
  <div>
    可以自己定义错误的界面,error.vue error

    <br />
    {{ error }}
    <br />
    <button @click="goHome">返回首页</button>
  </div>
</template>

<script setup lang="ts">
const props = defineProps({
  error: Object,
});

function goHome() {
  navigateTo("/");
}
</script>

<style scoped></style>

2.6.15 layout 布局

  • Layout布局是页面的包装器,可以将多个页面共性东西抽取到 Layout布局 中
  • Layout布局是使用< slot >组件来显示页面中的内容
  • Layout布局有两种使用方式
    • 方式一:默认布局
      • 在layouts目录下新建默认的布局组件,比如:layouts/default.vue
      • 然后在app.vue中通过< NuxtLayout >内置组件来使用
    • 方式二:自定义布局(Custom Layout)
      • 继续在layouts文件夹下新建 Layout 布局组件,比如: layouts/custom-layout.vue
      • 然后在app.vue中给内置组件 指定name属性 的值为:custom-layout

如果,在某些界面上需要展示,这个 布局组件的头部,有时候不需要展示,有下面这几个方案

  1. 可以在布局组件,判断路由,通过路由确定是否要展示
  2. 封装hooks
  3. pinia

2.6.16 plugins 插件

创建插件的方式

  • 方式一:直接使用 useNuxtApp() 中的 provide(name, vlaue) 方法直接创建,比如:可在App.vue中创建
    • useNuxtApp 提供了访问 Nuxt 共享运行时上下文的方法和属性(两端可用):provide、hooks、callhook、vueApp等
  • 方式二:在 plugins 目录中创建插件(推荐)
    • 顶级和子目录index文件写的插件会在创建Vue应用程序时会自动加载和注册
    • .server 或 .client 后缀名插件,可区分服务器端或客户端,用时需区分环境
  1. 在 plugins 目录下创建 plugins/price.ts 插件
  2. 接着 defineNuxtPlugin 函数创建插件,参数是一个回调函数
  3. 然后在组件中使用 useNuxtApp() 来拿到插件中的方法

插件注册顺序可以通过在文件名前加上一个数字来控制插件注册的顺序

plugins/1.price.ts 、plugins/2.string.ts、plugins/3.date.ts

export default defineNuxtPlugin((nuxt) => {
  return {
    provide: {
      // 创建vue 实例的时候,就会创建好
      formatPrice(price: number): string {
        const formatter = new Intl.NumberFormat("en-US", {
          style: "currency",
          currency: "USD",
          minimumFractionDigits: 2,
        });
        return formatter.format(price);
      },
    },
  };
});

const nuxtApp = useNuxtApp();
nuxtApp.provide("formatData", () => {
  return "2024-01-07";
});
console.log(nuxtApp.$formatData(), "是哦那个插件");
console.log(nuxtApp.$formatPrice(23), "plugins目录的擦火箭");

2.6.17 App 生命周期

App Hooks 主要可由 Nuxt 插件 使用 hooks 来监听 生命周期,也可用于 Vue 组合 API

但是,如在组件中编写hooks来监听,那 create和setup hooks就监听不了,因为这些hooks已经触发完了监听

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook("app:created", () => {
    console.log("The app is mounted!");
    // 执行一些操作...
  });
});

2.6.18 获取数据

  • $fetch:使用 $fetch 发起请求;这个方法会在 client 和 server 都会请求
  • useAsyncData:在刷新界面时,会减少客户端发起一次网络请求,但是切换路由啥的,还是会发;会阻塞页面导航
  • useFetch:就是 useAsyncData 的简写形式;会阻塞页面导航
    • 可以通过 useFetch 第二个参数 options 的 lazy 配置,value为true 则不会阻塞
    • 这个函数会返回 好多东西;useFetch · Nuxt Composables ,比如 refresh 可以刷新请求,调一下即可刷新,还有 pending,一开始为false ,网络发起的时候改成true ,结束改成 false
    • 如果 useFetch 的 options 请求参数 有 响应式数据,那么改成这个数据,也会自动发起请求
  • useLazyAsyncData:就是把 lazy 设置为了 true,不会阻塞界面导航,但是不确定接口返回值什么时候拿到,可以使用watch 监听
  • 这些函数只能用在 setup or Lifecycle Hooks 中
//1、$fetch:使用 $fetch 发起请求;这个方法会在 client 和 server 都会请求
 $fetch(BASE_URL + "/homeInfo", {
   method: "get",
 }).then(
   (res) => {
     console.log("$fetch", res);
   },
   (err) => {}
 );
// 2、useAsyncData:在刷新界面时,会减少客户端发起一次网络请求,但是切换路由啥的,还是会发
 const { data } = await useAsyncData("loginInfo", () => {
   return $fetch(BASE_URL + "/homeInfo");
 });
 console.log("useAsyncData", data);

// 3、useAsyncData的简写 useFetch
 const { data } = await useFetch(BASE_URL + "/homeInfo");
 console.log("useFetch", data);

// 4、useFetch get 请求 ,options 的设置
 const { data } = await useFetch("/homeInfo", {
   baseURL: BASE_URL,
   query: {
     name: "liujun",
   },
   // body: {}
   // headers: {}
 });
 console.log("useFetch", data);
// 5、useFetch post 请求
 const { data } = await useFetch("/goods", {
   method: "post",
   baseURL: BASE_URL,
   body: {
     count: 2,
   },
   // headers: {}
 });
 console.log("useFetch", data);

// 6、拦截器
// const { data } = await useFetch("/goods", {
//   method: "POST",
//   baseURL: BASE_URL,
//   body: {
//     count: 1,
//   },
//   // 请求的拦截 ( server and client )
//   onRequest({ request, options }) {
//     // console.log(options);
//     // options.headers = {
//     //   token: "xxxx",
//     // };
//   },
//   onRequestError({ request, options, error }) {
//     console.log("onRequestError");
//   },
//   onResponse({ request, response, options }) {
//     console.log("onResponse");
//     console.log(response._data.data.server_jsonstr);
//     response._data.data = {
//       name: "liujun",
//     };
//     // return response._data.data.server_jsonstr;
//   },
//   onResponseError({ request, response, options, error }) {
//     console.log("onResponseError");
//   },
// });
// console.log("拦截器", data.value);

// 7、useFetch 会阻导航内容的渲染
// const { data } = await useFetch("/homeInfo", {
//   baseURL: BASE_URL,
//   lazy:true,// 不会阻塞,可以用  useLazyFetch 也是一样的
//   query: {
//     name: "liujun",
//   },
//   // body: {}
//   // headers: {}
// });

2.6.19 server api

Nuxt3 提供了编写后端服务接口的功能,编写服务接口可以在server/api目录下编写

  1. 比如:编写一个 /api/homeinfo 接口
  2. 1.在server/api目录下新建 homeinfo.ts
  3. 2.接在在该文件中使用 defineEventHandler 函数来定义接口(支持 async)
  4. 3.然后就可以用useFetch函数轻松调用: /api/homeinfo 接口了
export default defineEventHandler((e) => {
  // let { req, res } = e.node
  // const query = getQuery(e)
  return {
    code: 200,
    data: {
      name: "liujun",
      age: 20,
    },
  };
});
// 浏览器中,http://localhost:3000/api/homeInfo
// 如果这个接口是 get 请求,可以在创建文件的时候 xxx.get.ts  也可以
// https://www.nuxt.com.cn/docs/guide/directory-structure/server

{
    "code": 200,
    "data": {
        "name": "liujun",
        "age": 20
    }
}

2.6.20 全局状态共享 useState

Nuxt跨页面、跨组件全局状态共享可使用 useState(支持Server和Client )

useState<T>(init?: () => T | Ref<T>): Ref<T>
useState<T>(key: string, init?: () => T | Ref<T>): Ref<T>
  • key: 一个唯一的键,确保数据获取在请求中被正确地去重。如果你不提供键,则会为 useState 的实例生成一个在文件和行号上唯一的键。
  • init: 当未初始化时,提供状态的初始值的函数。这个函数也可以返回一个 Ref
  • T: (仅 TypeScript)指定状态的类型

useState 具体使用步骤如下

  1. 在 composables 目录下创建一个模块,如: composables/states.ts
  2. 在states.ts中使用 useState 定义需全局共享状态,并导出
  3. 在组件中导入 states.ts 导出的全局状态

useState 只能用在 setup 函数 和 Lifecycle Hooks 中

useState 不支持classes, functions or symbols类型,因为这些类型不支持序列化

// 创建一个响应式状态并设置默认值

export default function useCount() {
  return useState("counter", () => 23); // 返回值是 ref
}

const res = useCount();
const addCount = () => {
  res.value++;
};

2.6.21 pinia

npm install @pinia/nuxt –-save # @pinia/nuxt 会处理state同步问题,比如不需要关心序列化或XSS 攻击等问题

npm install pinia –-save # 如有遇到pinia安装失败,可以添加 --legacy-peer-deps 告诉 NPM 忽略对等依赖并继续安装。或使用yarn

import { defineStore } from "pinia";

export interface IState {
  counter: number;
  homeInfo: any;
}

export const useHomeStore = defineStore("home", {
  state: (): IState => {
    return {
      counter: 0,
      homeInfo: {},
    };
  },
  actions: {
    increment() {
      this.counter++;
    },
    async fetchHomeData() {
      const url = "http://codercba.com:9060/juanpi/api/homeInfo";
      const { data } = await useFetch<any>(url);
      console.log(data.value.data);
      this.homeInfo = data.value.data;
    },
  },
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1367849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

迎接人工智能的下一个时代:ChatGPT的技术实现原理、行业实践以及商业变现途径

课程背景 2023年&#xff0c;以ChatGPT为代表的接近人类水平的对话机器人&#xff0c;AIGC不断刷爆网络&#xff0c;其强大的内容生成能力给人们带来了巨大的震撼。学术界和产业界也都形成共识&#xff1a;AIGC绝非昙花一现&#xff0c;其底层技术和产业生态已经形成了新的格局…

Linux-添加虚拟内存,不添加硬盘方式操作

在linux中&#xff0c;当物理内存mem不足时&#xff0c;就会使用虚拟内存(swap分区) 例如增加2G虚拟内存&#xff0c;操作如下: 1.查看内存大小 [rootlocalhost ~]# free -m 2.创建要作为swap分区的文件:增加1GB大小的交换分区&#xff0c;则命令写法如下&#xff0c;其中的cou…

探索区块链的未来:Ignis的母子架构进展与模块化区块链趋势

随着区块链技术的不断演进&#xff0c;模块化区块链成为热点&#xff0c;而其高拓展性的优点早在Ignis公链的母子架构上就已经实现。本文将探讨这两个方面&#xff0c;揭示它们如何推动区块链技术向前发展。 模块化区块链的兴起与Celestia 模块化区块链通过将不同的功能分解为…

开源C语言库Melon:Cron格式解析

本文介绍开源C语言库Melon的cron格式解析。 关于 Melon 库&#xff0c;这是一个开源的 C 语言库&#xff0c;它具有&#xff1a;开箱即用、无第三方依赖、安装部署简单、中英文文档齐全等优势。 Github repo 简介 cron也就是我们常说的Crontab中的时间格式&#xff0c;格式如…

一起来了解综合能源服务认证

首先&#xff0c;综合能源服务认证是有国家政策支持的&#xff0c; 《能源生产和消费革命战略&#xff08;2016-2030&#xff09;》中指出:1、能源生产端要以绿色低碳为方向&#xff0c;推动能源集中式和分布式开发并举&#xff0c;大幅提高新能源和可再生能源比重&#xff1b…

Async In C#5.0(async/await)学习笔记

此文为Async in C#5.0学习笔记 1、在async/await之前的异步 方式一&#xff1a;基于事件的异步Event-based Asynchronous Pattern (EAP). private void DumpWebPage(Uri uri) {WebClient webClient new WebClient();webClient.DownloadStringCompleted OnDownloadStringCo…

【大数据进阶第三阶段之ClickHouse学习笔记】ClickHouse的简介和使用

1、ClickHouse简介 ClickHouse是一种列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统&#xff0c;最初由俄罗斯搜索引擎公司Yandex开发&#xff0c;用于满足大规模数据分析和报告的需求。 开源地址…

01-shell

shell 1. shell概述 1.1 引入 完成以下任务: 判断用户家目录下&#xff08;~&#xff09;下面有没有一个叫 test 的文件夹如果没有&#xff0c;提示按 y 创建并进入此文件夹&#xff0c;按 n 退出如果有&#xff0c;直接进入&#xff0c;提示请输入一个字符串&#xff0c;并…

Qt/C++音视频开发63-设置视频旋转角度/支持0-90-180-270度旋转/自定义旋转角度

一、前言 设置旋转角度&#xff0c;相对来说是一个比较小众的需求&#xff0c;如果视频本身带了旋转角度&#xff0c;则解码播放的时候本身就会旋转到对应的角度显示&#xff0c;比如手机上拍摄的视频一般是旋转了90度的&#xff0c;如果该视频文件放到电脑上打开&#xff0c;…

探索PyTorch优化和剪枝技术相关的api函数

torch.nn子模块Utilities解析 clip_grad_norm_ torch.nn.utils.clip_grad_norm_ 是 PyTorch 深度学习框架中的一个函数&#xff0c;它主要用于控制神经网络训练过程中的梯度爆炸问题。这个函数通过裁剪梯度的范数来防止梯度过大&#xff0c;有助于稳定训练过程。 用途 防止…

数据权限-模型简要分析

权限管控可以通俗的理解为权力限制&#xff0c;即不同的人由于拥有不同权力&#xff0c;他所看到的、能使用的可能不一样。对应到一个应用系统&#xff0c;其实就是一个用户可能拥有不同的数据权限&#xff08;看到的&#xff09;和操作权限&#xff08;使用的&#xff09;。 …

基于ssm的双减后初小教育课外学习生活活动平台的设计与实现论文

双减后初小教育课外学习生活活动平台的设计与实现 摘 要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。以前学校对于课外学习活动信息的管理和控制&#xff0c;采用人工登记的方式保存相关…

RocketMQ5-02快速部署RocketMQ5.x(手动和容器部署)

RocketMQ5快速入门指南(含部署实践) 部署环境本机单机可执行包部署、Docker部署 Mac部署&#xff1a;下载源文件可执行包部署 NameServer 问题1&#xff1a;资源不足补充: 关于日志的输出 可执行包部署 Broker 对于Local模式对于Cluster模式 对于 ProxyDocker部署 NameServerD…

AcrelEMS-BP生物制药能效管理系统——安科瑞 顾烊宇

​01 行业方案 02 项目案例 安科瑞 顾烊宇

Koodo Reader : 一个开源免费的电子书阅读器

今天在浏览 GitHub 的时候&#xff0c;偶然发现了一个非常有趣的开源项目——Koodo Reader。这个项目是一款开源免费的电子书阅读器&#xff0c;支持多种格式。它具有一些非常独特的功能&#xff0c;深深地吸引了我的注意。在接下来的内容中&#xff0c;我将为大家详细介绍一下…

oracle 12c pdb expdp/impdp 数据导入导出

环境 (源)rac 环境 byoradbrac 系统版本&#xff1a;Red Hat Enterprise Linux Server release 6.5 软件版本&#xff1a;Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit byoradb1&#xff1a;172.17.38.44 byoradb2&#xff1a;172.17.38.45 (目的&am…

升级 Vite 5 出现警告 The CJS build of Vite‘s Node API is deprecated.

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

一、二进制方式 安装部署K8S

目录 一、操作系统初始化 1、关闭防火墙 2、关闭 SELinu 3、 关闭 swap 4、添加hosts 5、同步系统时间 二、集群搭建 —— 使用外部Etcd集群 1、自签证书 2、自签 Etcd SSL 证书 ① 创建 CA 配置文件&#xff1a;ca-config.json ② 创建 CA 证书签名请求文件&#xff…

how2heap-2.23-12-house_of_spirit

house_of_spirit 注意事项 house_of_spirit&#xff1a;将一个地址伪造成符合fast bin大小的chunk&#xff0c;将其释放进fastbin中&#xff0c;同时伪造其中的fd指针&#xff0c;达到任意地址分配 伪造的chunk的大小&#xff0c;为什么是fast bin大小范围内的chunk&#xff…

将项目同时提交到GitHub和码云Gitee上面,GitHub与Gitee同步

多个远程仓库同时使用 新建GitHub仓库 创建成功 在终端中创建仓库 如果你想在本地机器上创建Git仓库&#xff0c;或者想添加一个文件夹或文件到已经存在的Git仓库中&#xff0c;你应该在终端中创建你的Git仓库。在你可以通过终端来创建一个Git仓库。以下是在终端中创建Git仓…