Vue3使用mitt进行组件通信

mitt:事件总线,是第三方插件。

Vue2.x 使用 EventBus 事件总线进行兄弟组件通信,而在Vue3中 EventBus 事件总线模式已经被移除,官方建议使用外部的、实现了事件触发器接口的库,例如 mitttiny-emitter

比起 Vue 实例上的 EventBus,mitt.js 好在哪里呢?

  1. 首先它足够小,仅有200bytes。
  2. 其次支持全部事件的监听和批量移除。
  3. 它还不依赖 Vue 实例,可以跨框架使用,React 或者 Vue,甚至 jQuery 项目都能使用同一套库。

1、安装 mitt

npm install --save mitt

2、在公共文件 utils 下新建 mitter.ts文件,简单封装下 mitt

utils/mitter.ts

import mitt from 'mitt';

const mitter = mitt();

export default mitter;

在这里插入图片描述
在这里插入图片描述

3、使用

utils/request.ts

如果登录过期,派发 token-expired 事件。
在这里插入图片描述

import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { showMessage } from './errorCode';
import { alertController } from '@ionic/vue';
import { showToast } from '.';
import { StorageService } from './storageService';
import mitter from './mitter';

let token: string = '';
// 是否显示重新登录
let isReloginShow: boolean = false;

const storageService = new StorageService();
storageService.create();

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
// 创建axios实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_ENV == 'development' ? import.meta.env.VITE_APP_BASE_API : import.meta.env.VITE_APP_BASE_URL, // 设置API的基础URL
  timeout: 10000,   // 设置请求超时时间
});

const presentAlert = async () => {

  const alert = await alertController.create({
    header: '系统提示',
    message: '登录状态已过期,您可以继续留在该页面,或者重新登录',
    buttons: [
      {
        text: '取消',
        role: 'cancel',
        handler: () => {
          console.log('Alert canceled');
          isReloginShow = false;
        },
      },
      {
        text: '重新登录',
        role: 'confirm',
        handler: () => {
          console.log('Alert confirmed');
          isReloginShow = false;
          mitter.emit('token-expired');
        },
      },
    ],
  });

  await alert.present();
};

// 请求拦截器
service.interceptors.request.use(
  async (config: AxiosRequestConfig): Promise<any> => {
    // showLoading();
    // 是否需要设置 token    
    const isToken = (config.headers || {}).isToken === false
    const headers = config.headers || {};
    token = await storageService.getItem("token");
    if (token && !isToken) {
      headers['Authorization'] = 'Bearer ' + token; // 让每个请求携带自定义token 请根据实际情况自行修改
      // headers['token'] = token;
      config.headers = headers;
    }

    // return new Promise((resolve, reject) => {
    //   resolve(config)
    // })
    return config;
  },
  (error: AxiosError) => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // 对响应数据进行处理
    // 未设置状态码则默认成功状态
    const code = response.data.code || 200;
    // 获取错误信息
    const msg = response.data.msg || showMessage(code) || showMessage('default');
    // 二进制数据则直接返回
    if (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') {
      return response.data
    }
    if (code === 401) {
      if (!isReloginShow) {
        isReloginShow = true;
        presentAlert();
      }
      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
    } else if (code === 500) {
      showToast(msg);
      return Promise.reject(new Error(msg))
    } else if (code !== 200) {
      showToast(msg);
      return Promise.reject('error')
    } else {
      return response.data
    }
    // return response;
  },
  (error: AxiosError) => {
    // 处理响应错误
    return Promise.reject(error);
  }
);

export {
  service as request
}

src/HomePage.vue

在首页监听 token-expired 登录过期事件, 在离开页面时移出监听事件。

在这里插入图片描述

<script setup lang="ts">
import {
  IonPage,
  IonSearchbar,
  IonList,
  IonItem,
  IonLabel,
  IonSegment,
  IonSegmentButton,
  IonIcon,
  onIonViewWillEnter,
  onIonViewDidEnter,
  onIonViewWillLeave,
  modalController,
  IonNote,
  IonContent,
  IonHeader,
} from "@ionic/vue";
import { ref, inject } from "vue";
import * as echarts from "echarts";
import { StorageService } from "@/utils/storageService";
import { getAreaSituation, getCountrySamplePie, getNotify, getSampleInfo, getSampleInfoList } from "@/api/home";
import mitter from "@/utils/mitter";
import { useRouter } from "vue-router";
import HomeSearchDetails from "@/components/HomeSearchDetails.vue";
import { chevronForwardOutline } from "ionicons/icons";
import { QRScanner, registerKeyCodeReceiver, unregisterReceiver, UHFNotifyListeners, UHFRemoveAllListeners, addListenerRate, getEPC } from "@/utils/ratePlugin";
import { showToast } from "@/utils";

const router = useRouter();
const keyWords = ref<string | undefined>("");
const areaList = ref<any[]>([]);
const selectedArea = ref<any>(null);
const inventoryStatisticsPieChart = ref<HTMLElement | null>(null);
let pieChart: echarts.ECharts;
const seriesData = ref<any[]>([]);
const messageList = ref<string[]>([]);
const searchList = ref<any[]>([]);
const storageService = inject("storageService") as StorageService;

onIonViewWillEnter(async () => {
  const token = await storageService.getItem("token");
  const userInfo = await storageService.getItem("userInfo");
  // console.log(token, "首页token", JSON.parse(userInfo));
  getAreaList();
  getNotifyData();
});

onIonViewDidEnter(() => {
  window.addEventListener("resize", handleResize);
  mitter.on("token-expired", () => {
    // console.log("token失效,跳转到登录页面");
    router.push("/login");
  });
  getChartData();
});

onIonViewWillLeave(() => {
  window.removeEventListener("resize", handleResize);
  if (pieChart) {
    pieChart.dispose();
  }
  mitter.off("token-expired");

});

const handleInput = (event: Event) => {
  // keyWords.value = (event.target as HTMLInputElement).value;
  // console.log("搜索:", keyWords.value);
  searchList.value = [];
  if (keyWords.value) {
    getSampleInfo(keyWords.value).then((res: any) => {
      if (res.code === 200) {
        searchList.value = res.data;
      }
    })
  }
};

const segmentChange = (event: Event) => {
  let val: string = (event.target as HTMLInputElement).value;
  selectedArea.value = areaList.value.find((item) => item.areaName == val);
};

const initChart = () => {
  pieChart = echarts.init(inventoryStatisticsPieChart.value);
  let option = {
    title: {
      text: "99865",
      subtext: "库存总量",
      left: "14%",
      top: "center",
      textStyle: {
        fontSize: 20,
      },
      subtextStyle: {
        fontSize: 18,
      },
    },
    tooltip: {
      trigger: "item",
    },
    legend: {
      top: "center",
      type: "scroll",
      right: 0,
      orient: "vertical",
      formatter: (name: string) => {
        let total = 0;
        let target = 0;
        seriesData.value.forEach((item) => {
          total += item.value;
          if (item.name == name) {
            target = item.value;
          }
        });
        let percent = total ? ((target / total) * 100).toFixed(2) : 0;
        return `${name}  ${percent}% ${target}`;
      },
    },
    series: [
      {
        // name: "Access From",
        type: "pie",
        radius: ["70%", "90%"],
        right: "50%",
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: "center",
        },
        labelLine: {
          show: false,
        },
        data: seriesData.value,
      },
    ],
  };

  option && pieChart.setOption(option);
};

const handleResize = () => {
  setTimeout(() => {
    if (pieChart) {
      pieChart.resize();
    }
  }, 500);
};

const getAreaList = () => {
  getAreaSituation().then((res: any) => {
    if (res.code === 200) {
      areaList.value = res.data;
      selectedArea.value = areaList.value[0];
    }
  });
};

const getChartData = () => {
  getCountrySamplePie().then((res: any) => {
    if (res.code === 200) {
      seriesData.value = res.data;
      initChart();
    }
  });
};

const getNotifyData = () => {
  getNotify().then((res: any) => {
    if (res.code === 200) {
      messageList.value = res.data;
    }
  });
};

</script>

参考:Vue3 mitt 组件通信 - 附完整示例

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为大咖说 | 企业应用AI大模型的“道、法、术”—— 法:场景篇

本文作者&#xff1a;郑岩&#xff08;华为云AI变革首席专家&#xff09;全文约5000字&#xff0c;阅读约需10分钟 这是我的AI应用系列第二篇&#xff0c;想谈谈“如何找个好场景”。场景找对了&#xff0c;那就成功一大半&#xff0c;这个道理放在AI大模型的应用上&#xff0c…

谷歌为其AI搜索结果辩护,称问题出在“数据空白”和边缘案例|TodayAI

近日&#xff0c;谷歌 Google 在推出其AI生成的搜索结果后&#xff0c;引发了广泛争议。该公司表示&#xff0c;一些不准确的搜索结果是由于“数据空白”和边缘案例导致的。 上周&#xff0c;谷歌向数百万用户推出了AI搜索结果&#xff0c;旨在提供更好的搜索体验。然而&#…

[Redis]Hash类型

基本命令 hset命令 设置 hash 中指定的字段&#xff08;field&#xff09;的值&#xff08;value&#xff09; 返回值&#xff1a;添加的字段的个数&#xff08;注意是添加的个数&#xff0c;而不包括修改的&#xff09; hset key field value [field value ...] hget命令 …

RabbitMQ(三)SpringBoot整合,可靠性投递,死信队列,延迟队列,消费端限流,消息超时

文章目录 整合Springboot概述消费者生产者 消息可靠性投递故障原因解决方案生产者端消息确认机制&#xff08;故障情况1&#xff09;故障情况2解决方案故障情况3解决方案 消费端限流概念 消息超时概念队列层面&#xff1a;配置队列过期消息本身&#xff1a;配置消息过期 死信队…

GUI 01:GUI 编程概述,AWT 相关知识,Frame 窗口,Panel 面板,及监听事件的应用

一、前言 记录时间 [2024-05-30] 疑问导航 GUI 是什么&#xff1f;GUI 如何使用&#xff1f;GUI 有哪些应用&#xff1f; 学习目的 写一些自己心中的小工具&#xff1b;Swing 界面的维护&#xff1b;了解 MVC 架构&#xff0c;以及监听事件。 本文对图形用户界面&#xff08…

Django——Admin站点(Python)

#前言&#xff1a; 该博客为小编Django基础知识操作博客的最后一篇&#xff0c;主要讲解了关于Admin站点的一些基本操作&#xff0c;小编会继续尽力更新一些优质文章&#xff0c;同时欢迎大家点赞和收藏&#xff0c;也欢迎大家关注等待后续文章。 一、简介&#xff1a; Djan…

【Spring Cloud】微服务日志收集系统-ELK+Kafka

目录 任务背景本文相关文件资料Elasticsearch特性 LogstashKibanaELKELK的缺点引入消息中间件 ELKKafkaKafka概念 ELKKafka环境搭建1.将安装素材上传至服务器 cd /usr/local/soft2.防止Elasticsearch因虚拟内存问题启动失败3.创建镜像li/centos7-elasticsearch4.创建容器5.验证…

编译安装PHP服务(LAMP3)

目录 1.初始化设置&#xff0c;将安装PHP所需软件包传到/opt目录下 &#xff08;1&#xff09;关闭防火墙 &#xff08;2&#xff09;上传软件包到/opt目录 2.安装GD库和GD库关联程序&#xff0c;用来处理和生成图片 3.配置软件模块 4.编译及安装 5.优化把PHP 的可执行程…

先导微型数控桌面式加工中心

随着数控技术、传感器技术、人工智能等技术的不断发展&#xff0c;制造业的快速发展和技术的不断进步&#xff0c;小型五轴加工中心的性能将不断提升&#xff0c;五轴联动技术作为解决异性复杂零件高效优质加工问题的重要手段&#xff0c;使其具有更广泛的应用前景。小型五轴加…

【康耐视国产案例】智能AI相机:深度解析DataMan 380大视野高速AI读码硬实力

随着读码器技术的不断更新迭代&#xff0c;大视野高速应用成为当前工业读码领域的关键发展方向。客户对大视野高速读码器的需求源于其能显著减少生产成本并提升工作效率。然而&#xff0c;大视野应用场景往往伴随着对多个条码的读取需求&#xff0c;这无疑增加了算法的处理负担…

Playwright 自动化操作

之前有见同事用过playwright进行浏览器模拟操作&#xff0c;但是没有仔细了解&#xff0c;今天去详细看了下&#xff0c;发现playwright着实比selenium牛逼多了 Playwright 相对于selenium优点 1、自动下载chromnium, 无需担心chrome升级对应版本问题&#xff1b; 2、支持录屏操…

突破 LST/LRT 赛道中心化困境,Puffer Finance 何以重塑以太坊再质押未来

纵观过去的 2023 年&#xff0c;LST 赛道竞争进入“白热化”状态。去中心化、DeFi 增强、全链化成为市场争夺关键词&#xff0c;诸多 LST 赛道老牌项目纷纷陷入“中心化矛盾”&#xff0c;指责对方在以太坊去中心化进程中的不利作为。 在这样的竞争情形下&#xff0c;以太坊联…

从Socket到WebSocket

前言 不知道大家在学习网络编程的时候都是怎样的一种方式&#xff0c;我谨以此文章来记录我自己从头开始学习C网络编程时的经历&#xff0c;中间有许多我自己的一些想法和思考。当然作为一个刚开始学习的新手来说&#xff0c;有些内容也许不那么正确&#xff0c;只是代表了我在…

flink 操作mongodb的例子

简述 该例子为从一个Collection获取数据然后插入到另外一个Collection中。 Flink的基本处理过程可以清晰地分为以下几个阶段&#xff1a; 数据源&#xff08;Source&#xff09;&#xff1a; Flink可以从多种数据源中读取数据&#xff0c;如Kafka、RabbitMQ、HDFS等。Flink会…

通过 CXCR4 靶向纳米线修补细胞表面以抑制癌症转移

引用信息 文 章&#xff1a;Cell surface patching via CXCR4-targeted nanothreads for cancer metastasis inhibition. 期 刊&#xff1a;Nature Communications&#xff08;影响因子&#xff1a;16.6&#xff09; 发表时间&#xff1a;2024/3/29 作 者&#xff1…

基于springboot实现大学生一体化服务平台系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现大学生一体化服务平台系统演示 摘要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统大学生综…

vivado 时序约束

时间限制 以下ISE设计套件时序约束可以表示为XDC时序约束 Vivado设计套件。每个约束描述都包含一个UCF示例和 等效的XDC示例。 在未直接连接到边界的网络上创建时钟时&#xff0c;UCF和XDC不同 的设计&#xff08;如端口&#xff09;。在XDC中&#xff0c;当在上定义带有create…

LwIP 之十 详解 TCP RAW 编程、示例、API 源码、数据流

我们最为熟知的网络通信程序接口应该是 Socket。LwIP 自然也提供了 Socket 编程接口,不过,LwIP 的 Socket 编程接口都是使用最底层的接口来实现的。我们这里要学习的 TCP RAW 编程则是指的直接使用 LwIP 的最底层 TCP 接口来直接实现应用层功能。这里先来一张图,对 LwIP 内部…

【JS重点知识02】栈、堆与数据类型 关系

一&#xff1a;栈堆空间分配区别&#xff1a; 1 栈&#xff1a;由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈&#xff1b; 简单数据类型存放在栈中 2 堆&#xff1a;存储复杂数据类型&#xff08;对象&#xff09;&#xff0c;…

C#知识|通用数据访问类SQLHelper的编写

哈喽,你好啊,我是雷工! 前面学习了C#操作SQLServer数据库数据的增删改查, 《C#知识|通过ADO.NET实现应用程序对数据库的增、删、改操作。》 其中实现的过程中有很多代码是重复的,此时作为高阶程序员为了使代码更优雅,避免重复, 从而要考虑代码的复用技术,针对此案例中代…