【Vue】Nuxt最佳实践之常用库封装(二)

本文介绍了在Nuxt.js项目中如何进行工具类库的封装,包括持久化存储、事件通信和常用工具函数。同时,文章探讨了团队协作中的Git管理、组件规范和代码审查(CR)。分享了动态部署使用pm2的方法以及Git分支开发流程,强调了代码质量和注释的重要性。

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

Nuxt
站在巨人的肩膀上,以下代码借鉴于 cmn-utils 公共函数&请求封装,感谢作者 LANIF-UI 的开源贡献,有兴趣的小伙伴可以参考基于React+Dva的CMS后台管理系统 dva-boot

使用CRA(create-react-app v2) 构建的react dva 2 脚手架 支持动态路由、接口数据模拟、按功能分层、并且包含诸多实用的小组件

目录结构

  1. 常用工具类封装
    1.1 持久化存储方案
    1.2 事件巴士(Event Bus)
    1.3 常用的工具类函数
    1.4 如何批量导出
  2. 部署说明
    2.1 静态部署(generate)
    2.2 动态部署pm2简易实现
    2.3 自定义集群(ecosystem)
  3. 团队协同
    3.1 代码管理 Git
    3.2 组件规范
    3.3 说明文档
    3.4 code review(CR)

常用工具类封装

一个功能丰富和友好的方式来利用localStorage和sessionStorage (JSON、命名空间、扩展等)。

具体实现方式,npm i store2 vuex-persistedstate -S,实现思路,封装基本的增删改查至Store类,并结合 vuex-persistedstate 实现 vuex 持久化存储, 并单独新建一个js文件对外导出(避免多次实例化),即 单例模式

getStore = (key, alt) => this.store.get(key, alt) ES7 提案,暂未纳入标准语法,把函数直接作为一个arrow function的属性来定义,初始化的时候就绑定好了 this 指针

推荐阅读: ES6、ES7、ES8、ES9、ES10新特性一览

附我最认同的一句话,代码首先是给人看的,其次是在机器上运行,所以写好注释很重要哦~

import store from 'store2';
import {
   
    isObject, isFunction } from '../util';

export default class Store {
   
   
  constructor(namespace) {
   
   
    this.store = namespace ? store.namespace(namespace) : store;
    this.session = this.store.session;
    this.local = this.store.local;
  }

  /**
   * 反回一个新的store
   */
  create = (namespace) => new Store(namespace)

  /**
   * 将 value 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容
   * Examples:
   *
   *   .setStore('name', 'abc')
   *   .setStore({ name: 'abc', age: 18 }) // 一次存多个
   * @param {string | object} key 
   * @param {any} value 
   */
  setStore = (key, value) => {
   
   
    if (isObject(key)) {
   
   
      this.store.setAll(key);
    } else {
   
   
      this.store.set(key, value);
    }
    return this;
  }

  /**
   * 从本地缓存中异步获取指定 key 对应的内容, 如指定alt当没找到时反回alt
   * @param {string} key 
   * @return {Promise}
   */
  getStoreAsync = (key, alt) => Promise.resolve(this.store.get(key, alt))
  /**
   * 从本地缓存中同步获取指定 key 对应的内容, 如指定alt当没找到时反回alt
   * @param {string} key 
   * @param {any} alt
   */
  getStor
<think>好的,我需要回答用户关于在Nuxt3和Vue3中如何封装fetch并实现响应拦截的问题。首先,我需要回顾Nuxt3和Vue3中网络请求的不同之处。根据用户提供的引用,Nuxt3推荐使用内置的fetch而不是axios,而Vue3通常使用axios。用户想了解如何在这两个框架中封装请求并添加响应拦截。 首先,我应该先处理Nuxt3的部分。Nuxt3的封装可能涉及使用内置的useFetch或者$fetch,同时利用Nuxt3的插件系统来添加拦截器。引用[2]提到在nuxt.config.ts中配置模块,可能涉及到Pinia的状态管理,但用户的问题主要围绕请求封装,所以可能需要创建插件来拦截请求和响应。需要确认Nuxt3的插件如何编写,以及如何全局注册。 然后是Vue3的部分,用户可能更熟悉axios,所以需要展示如何封装axios实例,添加请求和响应拦截器。这部分相对标准,但需要确保示例代码正确,比如使用axios.create,以及正确设置拦截器。 另外,用户提供的引用[1]提到Nuxt3内置的fetch相关方法,可能需要详细说明在Nuxt3中使用$fetch,并如何通过插件或可组合函数进行封装。例如,可以覆盖全局的$fetch方法,或者在可组合函数中封装拦截逻辑。 需要注意区分Nuxt3和Vue3的不同实现方式,同时确保代码示例正确,比如语法、导入方式等。此外,响应拦截可能需要处理错误状态码,统一处理错误信息,或者处理授权失败跳转登录页等情况。 可能还需要考虑如何统一处理错误,例如在拦截器中捕获401状态码并重定向到登录页面,同时使用ElMessage提示错误信息。此外,在Nuxt3中可能需要使用运行时配置来设置baseURL,或者在请求时动态获取配置。 总结步骤: 1. Nuxt3中使用插件或可组合函数封装$fetch,添加请求和响应拦截。 2. Vue3中使用axios.create创建实例,添加拦截器。 3. 提供代码示例,确保语法正确,并符合各自框架的最佳实践。 4. 对比两种框架的实现方式,帮助用户理解差异。 5. 确保引用正确,比如引用中提到的模块配置和文档链接。 需要验证Nuxt3的插件写法是否正确,例如在plugins目录下创建http.ts文件,使用defineNuxtPlugin来定义插件,并在其中修改全局的$fetch行为。同时,处理请求拦截时添加headers,响应拦截处理错误。对于Vue3,使用axios的拦截器,并导出实例供组件使用。 可能还需要提到在Nuxt3中如何结合Pinia进行状态管理,例如在拦截器中检查token是否存在,但这可能超出当前问题范围,但如果有相关引用的话可以提及。不过用户的问题主要集中在封装和拦截,所以保持重点在这里。 最后,生成相关问题,可能涉及性能优化、错误处理、状态码处理等,确保问题与主题相关,帮助用户深入理解。</think>在Nuxt3和Vue3中实现`fetch`封装及响应拦截,需要区分框架特性。以下是分步实现方法: --- ### 一、Nuxt3中封装$fetch并实现拦截 #### 1. 创建插件统一拦截 在`plugins`目录下新建`http.ts`文件,通过覆盖全局`$fetch`实现拦截: ```typescript // plugins/http.ts export default defineNuxtPlugin(() => { const globalFetch = $fetch.create({ baseURL: useRuntimeConfig().public.apiBase, onRequest({ options }) { // 请求拦截:添加token const token = localStorage.getItem('token'); options.headers = { ...options.headers, Authorization: `Bearer ${token}` }; }, onResponseError({ response }) { // 响应拦截:处理401错误 if (response.status === 401) { ElMessage.error('登录过期'); navigateTo('/login'); } return Promise.reject(response._data); } }); return { provide: { fetch: globalFetch } }; }); ``` #### 2. 使用封装后的请求 ```typescript // 组件中调用 const { data } = await useFetch('/user/info', { method: 'GET' }); ``` --- ### Vue3中封装axios并实现拦截 #### 1. 创建axios实例 ```typescript // src/utils/http.ts import axios from 'axios'; const service = axios.create({ baseURL: import.meta.env.VITE_API_URL }); // 请求拦截 service.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }); // 响应拦截 service.interceptors.response.use( response => response.data, error => { if (error.response?.status === 401) { ElMessage.error('身份验证失败'); router.push('/login'); } return Promise.reject(error); } ); export default service; ``` #### 2. 在组件中使用 ```typescript import http from '@/utils/http'; http.get('/user/info').then(res => { console.log(res.data); }); ``` --- ### 关键差异对比 | 特性 | Nuxt3 | Vue3 | |--------------------|--------------------------------|----------------------| | 核心方法 | `useFetch`/`$fetch` | `axios` | | 错误处理 | 通过`onResponseError`钩子 | 拦截器`interceptors` | | 全局配置 | `useRuntimeConfig()`[^1] | 环境变量 | | 状态管理集成 | 支持Pinia插件[^2] | 需手动关联 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值