记录第一次使用Nuxt3

598 阅读2分钟

1.安装

保证node版本大于16.11

npx nuxi init <project-name>
// 打开生成的项目执行
npm install
// 运行项目
npm run dev

如果遇到报错Failed to download template from registry: request to https://raw.githubusercontent.com/nuxt/starter/templates/templates/v3.json failed, reason: getaddrinfo ENOENT raw.githubusercontent.com,把DNS改为114.114.114.114就可。

2.目录相关

Nuxt3中文文档:www.nuxt.com.cn

2.1 components

该目录是存放组件的地方,Nuxt会自动导入目录下的任何组件;如果你只想根据组件的名称而不是路径自动导入组件,那么你需要在配置文件中将pathPrefix选项设置为false

export default defineNuxtConfig({
  components: [
    {
      path: '~/components/',
      pathPrefix: false
    }
  ]
})

2.2 composables

这个目录是Nuxt3新增的,该目录下的方法会自动导入项目中,无需引入;主要作用是将常用逻辑和逻辑相关的代码抽象出来,以提高代码可复用性和可维护性。

// composables/counter.js
export const userCounter = () => {
  return useState('counter', () => 0)
}
// 组件
<template>
  <div>内容: {{ counter }} </div>
</template>

<script setup>
const counter = userCounter()
</script>

2.3 store

Nuxt3不再提供Vuex集成,推荐使用pinia。 文档地址:pinia.vuejs.org/zh/ssr/nuxt…

2.3.1安装使用

// 先安装包
npm install pinia @pinia/nuxt
// 在nuxt.config.js配置
export default defineNuxtConfig({
  // ... 其他配置
  modules: [
    '@pinia/nuxt'
  ]
})

3.pages

Nuxt3在新建文件命名时,将任何内容放在中括号内,它将被转换为动态路由参数;Nuxt2则需要以下划线作为前缀。

// Nuxt3
pages/
  company/
    [id].vue
    
// Nuxt2
pages/
  company/
    _id.vue

4.server

Nuxt3的服务端抽离了api、路由和中间件的功能到server文件夹;每个文件都应该导出一个用defineEventHandler()定义的默认函数。

4.1实现一个简单的接口

// 创建一个新文件server/api/demo.js
export default defineEventHandler((event) => {
  return {
    data: 'hello'
  }
})
// 使用await $fetch('/api/demo')调用这个api

响应结果: image.png

4.2做为中间层

做接口的合并或者处理成客户端想要的数据后然后返回

export default defineEventHandler(async (event) => {
  const res = await $fetch('接口地址', {
    query: { ...参数 }
  })
  if (res?.code === '0') {
    return {
      ...res.data
    }
  }
  return {
    data: null
  }
})

image.png

3.设置接口代理

Nuxt3使用了nitro作为dev server,所以配置vite代理不会生效。 文档地址:

export default defineNuxtConfig({
  // 只针对客户端请求的转发
  devProxy: {
    '/api': {
      target: 'https://example.com',
      changeOrigin: true,
      prependPath: true
    }
  },
  // 针对服务端的请求转发(这个对环境上也会生效)
  routeRules: {
    '/api/**': {
      proxy: 'https://example.com/**'
    }
  }
})

使用Nuxt3封装好的useFetch请求接口:

<script setup>
const res = await useFetch('接口地址', {
  baseURL: '/api',
  query: { ...参数 }
})
</script>

点击查看,这里看到文档结构已经返回了:

image.png

image.png

4.封装网络请求

对useFetch和$fetch进行简单的二次封装:

const baseURL = '/api'
// 拦截器
const interceptor = {
  onRequest({ request, options }) {
    // 设置请求头
  },
  onRequestError({ request, options, error }) {
    // 处理请求错误
  },
  onResponse({ request, response, options }) {
    // 处理响应数据
    if (response._data?.code !== '0') {
      return Promise.reject(response._data)
    }
  },
  onResponseError({ request, response, options }) {
    // 处理响应错误
  }
}

export function useFetch2(request, opts) {
  return useFetch(request, {
    baseURL,
    ...interceptor,
    ...opts
  })
}

export function useClientFetch(request, opts) {
  return $fetch(request, {
    baseURL,
    ...interceptor,
    ...opts
  })
}

...
post请求之类的封装

5.部署

执行npm run build会生成一个.output的目录,然后可以执行node .output/server/index.mjs在本地进行预览。

5.1 环境区分

image.png

我这边在package.json中配置了一些scripts:

{
  "scripts": {
    "build": "nuxt build",
    "build:test": "nuxi build --dotenv .env.test",
    "build:production": "nuxi build --dotenv .env.production",
    "dev": "nuxt dev",
    "start": "set PORT=8080 & node .output/server/index.mjs",
  }
}

在根目录新建相应的环境变量文件: image.png 可能会遇到客户端取不到环境变量的问题,有两种解决方案:

  • 使用vite的环境变量 VITE_APP_HOST=https://xxxxx
  • 将环境变量放在runtimeConfig中 image.png

5.2 系统区分

在服务器上部署也是执行相同的node命令,默认端口号是3000,运维可能会需要指定端口号

// windows使用
set PORT=8080 & node .output/server/index.mjs
// linux & mac
PORT=8080 node .output/server/index.mjs