Nuxt3初始化项目指南

本文介绍了如何使用Nuxt3初始化项目,调整项目结构,包括API目录、资产和组件等,以及如何封装请求接口和配置开发环境的代理。还提供了Nuxt3中文文档的链接作为参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇专栏基于笔者的Vue专栏,Nuxt3系列,如有不连贯之处可查看Nuxt3系列其他文章!特此说明

一、初始化项目

  • npx nuxi init <project-name>
  • cd <project-name>
  • npm install
  • npm run dev
    在这里插入图片描述

如果遇到npx nuxi init 失败,则先按照如下设置,如果不行的话,参考下图链接

在这里插入图片描述

二、调整项目结构

  • api/ ---- 用于存放接口相关内容
  • assets/ ----- 需要参加打包的静态资源
  • components/ -----组件
  • composables/ ------ 可复用逻辑(hooks, mixins)
  • config/ ------ 配置
  • layouts/ ------ 页面布局
  • middleware/ ------ 中间件
  • pages/ ------ 页面
  • plugins/ ------ 插件
  • public/ ------ 不需要参与打包的静态资源
  • server/ ------ 服务
  • store/ ------ 全局状态
  • types/ ------- 自定义类型
    在这里插入图片描述

三、封装请求接口

这里仅作举例,请根据实际情况进行配置

composables/useHttp.ts

import type { UseFetchOptions } from '#app';
import type { FetchResponse } from 'ofetch';

export interface Response<T> {
  data?: T
  code?: number
  message?: string
  success?: boolean
}
export type HttpOption<T> = UseFetchOptions<Response<T>>;

const handleError = <T>(response: FetchResponse<Response<T>> & FetchResponse<ResponseType>) => {
  const err = (text: string) => {
    // Message.error({
    //   content: response?._data?.message ?? text,
    //   icon: () => h(IconEmoticonDead),
    // })
  }
  if (!response._data) {
    err('请求超时,服务器无响应!')
    return
  }
  // const userStore = useUserStore()
  const handleMap: { [key: number]: () => void } = {
    404: () => err('服务器资源不存在'),
    500: () => err('服务器内部错误'),
    403: () => err('没有权限访问该资源'),
    401: () => {
      err('登录状态已过期,需要重新登录')
      // userStore.clearUserInfo()
      navigateTo('/login')
    },
  }
  handleMap[response.status] ? handleMap[response.status]() : err('未知错误!')
}

const fetch = <T>(url: string, option: UseFetchOptions<Response<T>>) => {
  return useFetch<Response<T>>(`/api/${url}`, {
    // 请求拦截器
    onRequest({ options }) {
      // 添加请求头,没登录不携带token
      // const userStore = useUserStore()
      // if (!userStore.isLogin) {
      //   return
      // }
      // options.headers = new Headers(options.headers)
      // options.headers.set('Authorization', `Bearer ${userStore.getToken}`)
    },
    // 响应拦截
    onResponse({ response }) {
      if (response.headers.get('content-disposition') && response.status === 200)
        return response
      // 在这里判断错误
      if (response._data.code !== 200) {
        handleError<T>(response)
        return Promise.reject(response._data)
      }
      // 成功返回
      return response._data
    },
    // 错误处理
    onResponseError({ response }) {
      handleError<T>(response)
      return Promise.reject(response?._data ?? null)
    },
    // 合并参数
    ...option,
  })
}

// 自动导出
export const useHttp = {
  get: <T>(url: string, params?: any, option?: HttpOption<T>) => {
    return fetch<T>(url, { method: 'get', params, ...option })
  },

  post: <T>(url: string, body?: any, option?: HttpOption<T>) => {
    return fetch<T>(url, { method: 'post', body, ...option })
  },

  put: <T>(url: string, body?: any, option?: HttpOption<T>) => {
    return fetch<T>(url, { method: 'put', body, ...option })
  },

  delete: <T>(url: string, body?: any, option?: HttpOption<T>) => {
    return fetch<T>(url, { method: 'delete', body, ...option })
  },
}

四、配置开发代理

通过server配置代理

server/middleware/proxy.ts

const { public: { apiBase } } = useRuntimeConfig()

export default defineEventHandler(async (event) => {
  if (event.node.req.url?.includes('/api')) {
    const { url, method, headers } = event.node.req;

    const options: any = {}
    options.method = method;
    options.headers = headers;
    if (method != "get" && method != "GET") {
      options.body = JSON.stringify(await readBody(event))
    }

    const resBody = await $fetch(apiBase + url, options);
    return resBody
  }
});

nuxt.config.ts

...
runtimeConfig: {
    public: {
      apiBase: "http://192.168.0.94:5569/",
    },
},
...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梨花炖海棠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值