当前位置: 首页 > news >正文

依赖注入+中央事件总线:Vue 3组件通信新玩法

​🌈个人主页:前端青山
🔥系列专栏:Vue篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来Vue篇专栏内容:Vue-依赖注入-中央事件总线

目录

中央事件总线使用

依赖注入使用

总结

中央事件总线

依赖注入

结言

大家好,依旧青山,

最近呢也随着需求的变更调优,加载数字孪生地图的缓慢,要将原有vue3+Ts数据大屏子菜单整合到一个地图环境下(注:无需加载其余地图场景,同一地图环境下切换不同菜单),也就是主页面及子菜单调用一次地图环境即可,页面很好集合前嵌套,但是不同页面对地图的操作该如何呢?

那么我首先做的就是封装一个公共的地图调用方法,以组件形式引入所有子菜单实现跨组件通信!

以数字孪生地图为例

import { ElLoading } from 'element-plus'
import mapJson from '@/utils/tjbhJson';
import textArr from '@/utils/textJson';
import cloudRenderer from "51superapi"
import { ref, onMounted, onBeforeUnmount,reactive,watchEffect } from "vue"
// 引入前缀路径
//封装51地图函数
const app = new cloudRenderer("mapDiv");
export default function (){let loadingInstance: any; // 在更宽泛的作用域定
const prefixUrl = import.meta.env.VITE_APP_BASE_API || '';
//配置51地图参数
const startRenderConfig = reactive({"url": "http://192.168.1.20:8080", //[必须] 云渲染服务地址; 8889:固定端口"order": "123456", //[必须] 渲染口令; 在云渲染客户端上获得"resolution": [window.innerWidth > 1920? 4096 : window.innerWidth,window.innerHeight >1080? 1209 : window.innerHeight], //[可选] 设置渲染场景像素分辨率"nodestyle": `width:${window.innerWidth > 1920? 4096 : window.innerWidth};height:${window.innerHeight >1080? 1209 : window.innerHeight};position:absolute;top:0px;left:0px;bottom:0px;right:0px;margin:auto;`, //[可选] 设置渲染场景容器DOM节点样式, 与设置渲染场景像素分辨率配对使用"keyboard": "keyboardnofn", //[可选] 初始建盘事件, 开启wasd方向键 [选项: keyboard/keyboardnofn; 详见注册键盘事件]"setlogmode": true, //[可选] 开启/关闭SuperAPI调用日志, 默认false
})
// 设置初始分辨率
startRenderConfig.resolution = [window.innerWidth > 1920 ? 4096 : window.innerWidth,window.innerHeight > 1080 ? 1209 : window.innerHeight,
];
//围绕中心旋转
let jsonData = {"time": 50,                      //相机旋转一周所需要的时间, (单位:秒)"direction": "stop"         //clockwise:顺时针; anticlockwise:逆时针; stop:停止旋转
}
//添加区域轮廓
let jsondata2 = {"id": "range_id","coord_type": 0,                  //坐标类型(0:经纬度坐标, 1:cad坐标)"cad_mapkey": "",                 //CAD基准点Key值, 项目中约定"coord_z": 0,                     //高度(单位:米)"coord_z_type": 0,                //坐标高度类型(0:相对3D世界表面;1:相对3D世界地面;2:相对3D世界海拔; 注:cad坐标无效)"type": "loop_line",                   //样式类型; 注①"color": "ffffff",              //轮廓颜色(HEXA颜色值)"range_height": 60,               //围栏高度(单位:米)"stroke_weight": 10,              //底部轮廓线宽度(单位:米; 注: 区域中含有内环"inner_points"时无效)"fill_area": "none",              //底部区域填充类型; 注②"geojson": mapJson,                 //geojson数据; 注③
​
}
//添加3d文字信息与区域轮廓
const pushAllCovering = () => {app.SuperAPI("Add3DText", textArr, (status: any) => {console.log(status); //成功、失败回调});//添加区域轮廓app.SuperAPI('AddGeoRange', jsondata2).then((_back: any) => {})
}
//初始地图视角
const Camejsondata = {"coord_type": 0,                                 //坐标类型(0:经纬度坐标, 1:cad坐标)"cad_mapkey": "",                                //CAD基准点Key值, 项目中约定"coord_z": "2.06",                               //海拔高度(单位:米)"center_coord": "117.689178,39.01527",           //中心点的坐标 lng,lat"arm_distance": 3000,                            //镜头距中心点距离(单位:米)"pitch": 30,                                     //镜头俯仰角(5~89)"yaw": 70,                                        //镜头偏航角(0正北, 0~359)"fly": true                                      //true: 飞行动画(有一个短暂飞行动画,并按照arm_distance,pitch,yaw设置镜头);//false: 立刻跳转过去(瞬移)
}
//设置渲染质量
let jsonDate ={"quality": "epic"   //low:低; medium:中; high:高; epic:超高;
}
// 地图事件注册函数
const myHandleResponseFunction = (data: string) => {const jsonObject = typeof data === "object" ? JSON.parse(JSON.stringify(data)) : JSON.parse(data);switch (jsonObject.func_name) {case "APIAlready":app.SuperAPI("RemoveAllCovering", {covering_type: "all", //覆盖物类型, 详见下表}).then((_back: any) => {console.log(_back);});pushAllCovering(); //添加区域轮廓//设置镜头绕场景中心点旋转app.SuperAPI("SetCameraRotate", jsonData, (e: any) => {
​})//设置当前场景镜头视界app.SuperAPI("SetCameraInfo", Camejsondata, (status: any) => {})app.SuperAPI("SetRenderQuality", jsonDate, (status:any) => {console.log(status,'设置渲染质量'); //成功、失败回调})loadingInstance.close();break;case 'OnPOIClick':const coord = jsonObject.args.coord;const poiId = jsonObject.args.id;console.log(poiId,"poiId")break;}return data;
}
const myStartRender = async () => {try {// 设置初始分辨率
startRenderConfig.resolution = [window.innerWidth > 1920 ? 4096 : window.innerWidth,window.innerHeight > 1080 ? 1209 : window.innerHeight,
];await app.startRender(startRenderConfig).then((el: any) => {loadingInstance = ElLoading.service({ // 赋值给外部变量lock: true,text: '地图加载中',background: 'rgba(0, 0, 0, 0.7)',});// 事件注册;事件监听处理器函数, 接收所有从云渲染返回的事件, 数据等信息app.RegisterCloudResponse(myHandleResponseFunction);})} catch (error) {console.error("error:", error)}
}
const SuperAPI = () => {//先删除全部覆盖物                      覆盖物类型, 详见下表app.SuperAPI("RemoveAllCovering", { "covering_type": "poi" }, (status: any) => {console.log(status); //成功、失败回调})
}
// 监听窗口大小变化
watchEffect(() => {startRenderConfig.resolution = [window.innerWidth > 1920 ? 4096 : window.innerWidth,window.innerHeight > 1080 ? 1209 : window.innerHeight,];
});
return { app, startRenderConfig, myStartRender, myHandleResponseFunction,prefixUrl,loadingInstance, SuperAPI }
}

把公共地图渲染部分封装为一个ts文件,并暴露出myStartRender函数方便在主页面onMounted函数中调用并渲染地图,依次执行即可,那么大家可以看到还暴露出一个app进行全局调用,是因为这个数字孪生地图的操作都要以app.(地图操作Api)的形式调用

最终我们在页面中删除公共部分,只需引入公共函数即可!

<template><div id="main-content"><!-- 地图盒子 --><div id="mapDiv"></div><Header :naturalHazards="header"/><div v-if="header == '主页面'"><NaturalHazard/></div><div v-else-if="header == '菜单一'"><EarlyWarningDetection /></div><div v-else-if="header == '菜单二'"><DisasterGeneralData /></div><div v-else-if="header == '菜单三'"><JobFacilities /></div><div v-else-if="header == '菜单四'"><RiskHiddenDanger /></div><div v-else-if="header == '菜单五'"><VideoSurveillance /></div><div v-else-if="header == '菜单六'"><HydrologicMonitoring /></div><div v-else-if="header == '菜单七'"><FloodFightingMaterials /></div><div v-else-if="header == '菜单八'"><RescueTeam /></div></div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick, provide } from "vue";
//引入51地图SuperAPI
import useSuperApi from "@/utils/useSuperApi"
const {app, prefixUrl,SuperAPI,
} = useSuperApi()
onMounted(() => {nextTick(() => {myStartRender()})
});
onBeforeUnmount(() => {app.StopRenderCloud(); //关闭云渲染, 释放资源
​
})
</script>

那么随之而来问题也就来了,当地图出现poi点的时候,我们点击对应的poi点肯定要实现不同的事件,我们现在所封装的app暴露出来可以进行打点操作,点击poi点的操作是由地图函数内部执行

// 地图事件注册函数
const myHandleResponseFunction = (data: string) => {const jsonObject = typeof data === "object" ? JSON.parse(JSON.stringify(data)) : JSON.parse(data);switch (jsonObject.func_name) {case 'OnPOIClick':const coord = jsonObject.args.coord;const poiId = jsonObject.args.id;console.log(poiId,"poiId"点击poi点所获得的id及经纬度)break;}return data;
}

在没有整合之前调用的时候是在当前页面的地图函数下执行,请看下方

// 地图事件注册函数
const myHandleResponseFunction = (data: string) => {const jsonObject = typeof data === "object" ? JSON.parse(JSON.stringify(data)) : JSON.parse(data);switch (jsonObject.func_name) {case 'OnPOIClick':const coord = jsonObject.args.coord;const poiId = jsonObject.args.id;handlePOIClick(poiId, coord);break;}return data;
​
}
// 处理自定义POI Label点击事件的函数
const handlePOIClick = (poiId: string, coord: string) => {const [type, id] = poiId.split('_'); // 分割前缀和IDswitch (type) { // 假设id格式为"type_ID",通过前缀区分类型case 'ggwhcs'://公共文化场所handelGgwhcs(id);break;case 'lyjq'://旅游景区handelLyjq(id);break;default:console.log(`未识别的POI类型: ${poiId}`);break;}
}

那么现在我们封装成一个公共函数,且渲染地图只在主页面调用,就要想办法将函数内部的poiId和coord作为参数暴露出去,方便我们每个子页面调用执行不同的操作,这里我就想到了vue的中央事件总线和依赖注入!

Vue3提供了多种机制来支持组件间的通信,包括中央事件总线和依赖注入。选择哪种方式取决于具体的应用场景和需求

中央事件总线使用

在处理地图的poi点点击事件时,我们可以先使用中央事件总线来执行我们组件不同页面点击poi点的处理逻辑,

首先,在utils文件夹下创建一个EventBus.ts文件

//封装中央事件总线
class EventBus {private events: Record<string, Function[]> = {};
​on(event: string, callback: Function) {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(callback);}
​off(event: string, callback: Function) {if (!this.events[event]) return;this.events[event] = this.events[event].filter(cb => cb !== callback);}
​emit(event: string, ...args: any[]) {if (!this.events[event]) return;this.events[event].forEach(callback => callback(...args));}
}
​
const eventBus = new EventBus();
export default eventBus;

main.ts中创建一个全局的事件总线

app.config.globalProperties.$bus = {}; // 直接在全局属性中创建事件总线

然后再封装的内部地图函数poi点击事件时进行发送事件

case 'OnPOIClick':const coord = jsonObject.args.coord;const poiId = jsonObject.args.id;console.log(poiId,"poiId")eventBus.emit('poi-click', poiId, coord); // 发送事件break;

然后再主页面和各个子页面引入eventBus,在onMountedonBeforeUnmount监听和移出事件总线

onMounted(() => {nextTick(() => {eventBus.on('poi-click', handlePOIClick);//handlePOIClick为poi点击事件init();//初始化函数})
});
onBeforeUnmount(() => {//移出监听eventBus.off('poi-click', handlePOIClick);
})

这时,不管是我们的主页面,还是子菜单,都可以在切换的时候对应页面的poi点进行不同的处理逻辑了

依赖注入使用

单个菜单调用地图不同服务的事情解决了,那子菜单和主页面或子菜单和子菜单之间还有通信的复杂操作呢

比如在主页面的Echarts图表中,柱状图列出了A页面和B页面的统计数据,当我点击不同的柱状图时要切换到当前菜单,并直接选中状态及地图出现对应的操作,这时,基于这种复杂的操作我们可以使用依赖注入

在主页面先通过ref绑定对应组件,并引入provide提供依赖

<template><div id="main-content"><!-- 地图盒子 --><div id="mapDiv"></div><Header :naturalHazards="header"/><div v-if="header == '主页面'"><NaturalHazard/></div><div v-else-if="header == '菜单一'"><EarlyWarningDetection /></div><div v-else-if="header == '菜单二'" ref="disasterGeneralData"><DisasterGeneralData /></div><div v-else-if="header == '菜单三'"><JobFacilities /></div><div v-else-if="header == '菜单四'"><RiskHiddenDanger /></div><div v-else-if="header == '菜单五'"><VideoSurveillance /></div><div v-else-if="header == '菜单六'"><HydrologicMonitoring /></div><div v-else-if="header == '菜单七'"><FloodFightingMaterials /></div><div v-else-if="header == '菜单八'"><RescueTeam /></div></div>
</template>
​
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
import { ref, onMounted, onBeforeUnmount, nextTick, provide } from "vue";
eam/index.vue";
import useSuperApi from "@/utils/useSuperApi";
import eventBus from '@/utils/EventBus';
const {app, myStartRender,prefixUrl,SuperAPI
} = useSuperApi()
const header = ref<any>("自然灾害")
let disasterGeneralData = ref<any>()
const setNames = (name: any) => {//这里我们提供一个函数来接收传进来的name
}
provide("setNames",setNames)
onMounted(() => {nextTick(() => {myStartRender()})
});
onBeforeUnmount(() => {app.StopRenderCloud(); //关闭云渲染, 释放资源
​
})
</script>
​
<style scoped lang="scss">
​
</style>

然后在我们的图表组件页面中注入依赖

let setNames: any = inject("setNames")

当我们点击对应的echarts图表时

      zgrwczqktance.value.on('click', (params: any) => {nextTick(() => {setNames(params.name)//传入对应name})});

那么我们子菜单页面肯定是要通过传入的name来执行不同的地图操作或展示详情等逻辑...

const setName = (name: any) => {const mappings:any = {"菜单一": [1, '菜单一'],"菜单二": [3, '菜单二'],"菜单三": [6, '菜单三'],"菜单四": [11, '菜单四'],"菜单五": [7, '菜单五'],};const [id, description] = mappings[name] || [];if (id !== undefined) {(name === "菜单一" || name === "菜单二" || name === "菜单四" || name === "菜单五" || name === "菜单三")? abreastClicks(id, description): abreastClick(id, description);}
};

然后我们把这个方法通过defineExpose给暴露出去

defineExpose({setName
})

最后在我们的主页面通过ref所绑定实例再取到依赖注入传入的参数和暴露的内部方法来进行通信啦

let disasterGeneralData = ref<any>()//ref绑定实例
const setNames = (name: any) => {disasterGeneralData.value.setName(name)//子菜单内部的setName方法(已暴露)
}

总结

中央事件总线
  • 优点

    • 简单易用,适用于较小规模的应用程序。

    • 不需要修改现有组件即可添加新的监听器。

  • 缺点

    • 随着应用规模的增长,事件名称可能会变得难以管理和追踪。

    • 可能导致组件间的耦合度增加。

依赖注入
  • 优点

    • 更好的组织性和可维护性,因为依赖关系是显式的。

    • 适用于需要在多个组件间共享数据和服务的情况。

    • 支持树状结构中的组件通信,无需直接父子关系。

  • 缺点

    • 对于简单的通信场景可能显得过于复杂。

    • 如果过度使用,可能会导致组件之间过于紧密的耦合。

结言
  • 对于简单的跨组件通信,可以考虑使用中央事件总线。

  • 对于更复杂的通信需求,依赖注入提供了更好的组织性和可维护性。

相关文章:

依赖注入+中央事件总线:Vue 3组件通信新玩法

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Vue篇专栏内容:Vue-依赖注入-中央事件总线 目录 中央事件总线使用 依赖注入使用 总结 中央事件总线 依赖注入…...

EasyCVR视频汇聚平台构建远程安防监控:5大亮点解析,助力安防无死角

随着科技的飞速发展&#xff0c;远程安防监控系统已经成为现代社会中不可或缺的一部分&#xff0c;无论是在小区、公共场所还是工业领域&#xff0c;安防监控都发挥着至关重要的作用。而EasyCVR作为一款功能强大的视频监控综合管理平台&#xff0c;其在构建远程安防监控系统方面…...

fastadmin安装插件报500的错误

项目场景&#xff1a; 项目新建后&#xff0c;想在本地项目中安装相关的插件&#xff0c;但是在插件管理页面点击安装的时候一直报500的错误。 问题描述 我们将项目中的调试打开&#xff0c;在application/config.php里修改 app_debug&#xff0c;将false改为true&#xff0c…...

速盾:为什么需要服务器和cdn?

在互联网时代&#xff0c;服务器和CDN&#xff08;内容分发网络&#xff09;起着非常重要的作用。它们是实现高效、稳定和可靠网络服务的关键组成部分。下面我将详细阐述为什么需要服务器和CDN。 首先&#xff0c;服务器是互联网上存储、处理和传输数据的中心枢纽。当我们在浏…...

十四、模拟实现 list 类

Ⅰ . list 基本框架的实现 01 结点的建立 为了实现链表&#xff0c;我们首先要做的应该是建立结点 为了和真正的 list 进行区分&#xff0c;我们仍然在自己的命名空间内实现 代码实现&#xff1a; namespace yxt {// 建立结点template<class T>struct ListNode{T _d…...

JavaScript简介之引入方式

JavaScript 引入方式 提问&#xff1a;CSS的引入方式&#xff1f;在学习 JavaScript 语法之前&#xff0c;我们首先要知道在哪里写 JavaScript 才行。想要在 HTML 中引入 JavaScript&#xff0c;一般有 3 种方式。 外部 JavaScript 内部 JavaScript 元素事件 JavaScript&#…...

同一台电脑上安装不同版本的nodejs(搭配VSCode)

今天拉取了一个前后端分离的项目&#xff0c;运行前端的时候&#xff0c;出现node版本不匹配的情况。 本文章将从安装node.js开始到VSCode使用进行讲解 1、去官网下载node版本 以16版本为例&#xff0c;需要哪个版本&#xff0c;就在网址上把版本号替换即可 https://nodejs.o…...

python小游戏之摇骰子猜大小

最近学习Python的随机数&#xff0c;逻辑判断&#xff0c;循环的用法&#xff0c;就想找一些练习题&#xff0c;比如小游戏猜大小&#xff0c;程序思路如下&#xff1a; 附上源代码如下&#xff1a; 摇骰子的函数&#xff0c;这个函数其实并不需要传任何参数&#xff0c;调用后…...

C++入门——12继承

1.继承 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层次结构&#xff0c;体现了由简…...

Python做统计图之美

Python数据分析可视化 案例效果图 import pandas as pd import matplotlib.pyplot as plt import matplotlib# 数据 data {"房型": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],"住宅类型": ["普通宅", "普通宅", "普通宅", &q…...

激光雷达点云投影到图像平面

将激光雷达点云投影到图像平面涉及几何变换和相机模型的应用。以下是该过程的基本原理&#xff1a; 1. 坐标系转换 激光雷达生成的点云通常位于激光雷达的坐标系中&#xff0c;而图像则在相机坐标系中。为了将点云投影到图像上&#xff0c;首先需要将点云从激光雷达坐标系转换…...

[python]将anaconda默认创建环境python版本设置为32位的

首先看看gpt怎么回答的 装了Anaconda。如果尚未安装&#xff0c;可以从Anaconda官网下载适合你的操作系统的安装程序&#xff0c;并按照安装向导进行安装。 二、创建32位Python环境 在Anaconda中&#xff0c;你可以通过修改环境变量来尝试切换到32位模式&#xff08;尽管这并…...

Jmeter+Influxdb+Grafana平台监控性能测试过程(三种方式)

一、Jmeter自带插件监控 下载地址&#xff1a;Install :: JMeter-Plugins.org 安装&#xff1a;下载后文件为jmeter-plugins-manager-1.3.jar&#xff0c;将其放入jmeter安装目录下的lib/ext目录&#xff0c;然后重启jmeter&#xff0c;即可。 启动Jmeter&#xff0c;测试计…...

[创业之路-135] :ERP、PDM、EDM、Git各种的用途和区别,硬件型初创公司需要哪些管理工具?

目录 前言&#xff1a; 一、ERP&#xff08;企业资源计划&#xff09; 二、PDM&#xff08;产品数据管理系统&#xff09; 三、EDM&#xff08;文档管理系统&#xff0c;有时也指电子邮件营销&#xff09; 四、Git 总结 五、硬件研发、生产型企业需要哪些管理工具&#…...

通过剪枝与知识蒸馏优化大型语言模型:NVIDIA在Llama 3.1模型上的实践与创新

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

DOM型xss靶场实验

xss是什么&#xff1f; XSS是一种经常出现在web应用中的计算机安全漏洞&#xff0c;它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制--例如同源策略(same origin policy)。这种类型的漏洞由…...

华为---端口隔离简介和示例配置

目录 1. 端口隔离概念 2. 端口隔离作用 3. 端口隔离优点 4. 端口隔离缺点 5. 端口隔离的方法和应用场景 6. 端口隔离配置 6.1 端口隔离相关配置命令 6.2 端口隔离配置思路 7. 示例配置 7.1 示例场景 7.2 网络拓扑图 7.3 基本配置 7.4端口隔离配置与验证 7.4.1 双…...

Android 架构模式之 MVC

目录 架构设计的目的对 MVC 的理解Android 中 MVC 的问题试吃个小李子ViewModelController 大家好&#xff01; 作为 Android 程序猿&#xff0c;MVC 应该是我们第一个接触的架构吧&#xff0c;从开始接触 Android 那一刻起&#xff0c;我们就开始接触它&#xff0c;可还记得我…...

节点使用简介:comfyui-photoshop

1、安装comfyui-photoshop 略过 一点要注意的是&#xff1a;在Photoshop上的安装增效工具&#xff0c;要通过Creative Cloud 桌面应用程序进行安装&#xff0c;才能成功在增效工具中显示&#xff0c;直接通过将文件解压到Plug-ins路径行不通&#xff08;至少对我来说行不通&am…...

使用Go语言将PDF文件转换为Base64编码

使用 Go 语言将 Base64 编码转换为 PDF 文件-CSDN博客本文介绍了如何使用 Go 语言将 Base64 编码转换为 PDF 文件&#xff0c;并保存到指定路径。https://blog.csdn.net/qq_45519030/article/details/141225772 在现代编程中&#xff0c;数据转换和编码是常见的需求。本文将介绍…...

XSS Game

关卡网址&#xff1a;XSS Game - Learning XSS Made Simple! | Created by PwnFunction 1.Ma Spaghet! 见源代码分析得&#xff0c;somebody接收参数&#xff0c;输入somebody111查看所在位置 使用input标签 <input onmouseoveralert(1337)> 2.Jefff jeff接收参数,在ev…...

???牛客周赛55:虫洞操纵者

题目描述 \,\,\,\,\,\,\,\,\,\,你需要在一个可以上下左右移动的 nnn\times nnn 棋盘上解开一个迷宫&#xff1a;棋盘四周都是墙&#xff1b;每个方格要么是可以通过的空方格 ′0′\sf 0′0′ &#xff0c;要么是不可通过的墙方格 ′1′\sf 1′1′ &#xff1b;你可以沿着空方格…...

Unity3D开发之OnCollisionXXX触发条件

A和B碰撞触发OnCollision函数条件如下&#xff1a; 1.A和B都要有collider。&#xff08;子物体有也可以&#xff09; 2.A和B至少有一个刚体&#xff08;Rigidbody&#xff09;组件&#xff0c;且刚体的isKinematic为false。如果为true不会触发。 3.挂载脚本的物体必须有刚体…...

spfa()算法(求最短路)

spfa算法是对bellman_ford算法的优化&#xff0c;大部分求最短路问题都可以用spaf算法来求。 注意&#xff1a; &#xff08;1&#xff09;如若图中有负权回路&#xff0c;不能用spfa算法&#xff0c;要用bellman_ford算法&#xff1b;若只有负权边&#xff0c;则可以用 spf…...

聊聊国产数据库的生态系统建设

生态系统是指在自然界中&#xff0c;生物与环境构成统一的整体&#xff0c;之间相互影响相互制约&#xff0c;并在一定时期内处于相对稳定的动态平衡状态。所谓数据库的生态系统&#xff0c;从用户的角度看&#xff0c;就是充分打通产品使用过程中上下游的关联&#xff0c;使其…...

JDK源码解析:LinkedList

1、背景 我们咨询一下腾讯混元大模型&#xff0c;什么是“LinkedList”。 以下是混元大模型的回答&#xff1a; LinkedList 是 Java 集合框架中的一种数据结构&#xff0c;它实现了 List 和 Deque 接口。LinkedList 是一个双向链表&#xff0c;这意味着每个元素都包含对前一个和…...

drawio的问题

drawio的问题 先给出drawio的链接https://app.diagrams.net/ 我在用overleaf写论文的过程中&#xff0c;发现了一个问题&#xff0c;就是使用drawio画好图之后&#xff0c;只能保存以下几个选项&#xff1a; 但是不管是什么类型&#xff0c;在overleaf上面图片都不显示。如果…...

零基础学习Redis(3) -- Redis常用命令

Redis是一个 客户端-服务器 结构的程序&#xff0c;Redis客户端和服务器可以在同一台主机上&#xff0c;也可以在不同主机上&#xff0c;客户端和服务器之间通过网络进行通信。服务器端负责存储和管理数据。客户端则可以通过命名对服务端的数据进行操作。 Redis客户端有多种&a…...

响应式Web设计:纯HTML和CSS的实现技巧-1

响应式Web设计&#xff08;Responsive Web Design, RWD&#xff09;是一种旨在确保网站在不同设备和屏幕尺寸下都能良好运行的网页设计策略。通过纯HTML和CSS实现响应式设计&#xff0c;主要依赖于媒体查询&#xff08;Media Queries&#xff09;、灵活的布局、可伸缩的图片和字…...

FrereRTOS事件组

文章目录 一、事件组概念与操作1、事件组的概念2、事件组的操作 二、事件组函数1、创建2、删除3、设置事件4、等待事件5、同步点 三、示例&#xff1a;广播四、示例&#xff1a;等待一个任意事件五、示例: 等待多个事件都发生 学校组织秋游&#xff0c;组长在等待&#xff1a; …...

【经典算法】BFS_最短路问题

目录 1. 最短路问题介绍2. 算法原理和代码实现(含题目链接)1926.迷宫中离入口最近的出口433.最小基因变化127.单词接龙675.为高尔夫比赛砍树 3. 算法总结 1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问…...

【题目/训练】:双指针

引言 我们已经在这篇博客【算法/学习】双指针-CSDN博客里面讲了双指针、二分等的相关知识。 现在我们来做一些训练吧 经典例题 1. 移动零 思路&#xff1a; 使用 0 当做这个中间点&#xff0c;把不等于 0(注意题目没说不能有负数)的放到中间点的左边&#xff0c;等于 0 的…...

LLVM - 编译器后端-指令选择

一&#xff1a;概述 任何后端的核心都是指令选择。LLVM 实现了几种方法&#xff1b;在本篇文章中&#xff0c;我们将通过选择有向无环图&#xff08;DAG&#xff09;和全局指令选择来实现指令选择。 在本篇文章中&#xff0c;我们将学习以下主题&#xff1a; • 定义调…...

ES+FileBeat+Kibana日志采集搭建体验

1.环境准备 需要linux操作系统&#xff0c;并安装了docker环境 此处使用虚拟机演示。&#xff08;虚拟机和docker看参考我之前写的文章&#xff09; VirtualBox安装Oracle Linux 7.9全流程-CSDN博客 VirtualBox上的Oracle Linux虚拟机安装Docker全流程-CSDN博客 简单演示搭建ES…...

Dockerfile常用指令详解

Dockerfile 是一个用于定义 Docker 镜像构建过程的脚本文件&#xff0c;其中包含了一系列指令&#xff0c;用于指定如何构建和配置镜像。以下是一些常用的 Dockerfile 指令及其示例用法&#xff1a; 1. FROM 指定基础镜像&#xff0c;Dockerfile 必须以该指令开始。 示例&am…...

【vue】浏览器兼容相关

Vue.js 是一个流行的前端 JavaScript 框架&#xff0c;它支持构建单页应用和复杂的用户界面。Vue.js 的核心库本身对浏览器的支持情况如下&#xff1a; Vue.js 2.x 最低支持版本&#xff1a;IE9 及以上版本。特性支持&#xff1a;ES5。兼容性&#xff1a;Vue 2.x 在发布时就考…...

【区块链+金融服务】基于区块链的区域股权金融综合服务平台 | FISCO BCOS应用案例

区域性股权市场是我国资本市场的重要组成部分&#xff0c;是多层次资本市场体系的基石。区块链技术与区域性股权市场 分散特征天然匹配&#xff0c;从新型金融基础设施层面为场外参与各方提供公共的可信服务&#xff0c;以技术手段完善市场基础条 件&#xff0c;弥补区域性短板…...

string字符串和json对象相互转换问题

//响应体String responseStr EntityUtils.toString(response.getEntity());log.debug("下单响应码:{},响应体:{}",statusCode,responseStr);if(statusCode HttpStatus.OK.value()){JSONObject jsonObject JSONObject.parseObject(responseStr);if(jsonObject.cont…...

【生成式人工智能-十一一个不修改模型就能加速语言模型生成的方法】

一个加速语言模型生成的方法 现在语言模型的一个弊端speculative decoding预言家预测的问题 speculative decoding 模块的实现方法NAT Non-autoregressive模型压缩使用搜索引擎 一些更复杂些的speculative decoding 实现方式 speculative decoding 是一个适用于目前生成模型的加…...

Rust 错误处理

Rust 错误处理 Rust 是一种系统编程语言,以其内存安全、高并发和实用性而著称。在 Rust 中,错误处理是一个核心概念,它通过提供 Result 和 Option 类型来鼓励开发者显式地处理可能出现的错误,而不是依赖异常机制。本文将深入探讨 Rust 中的错误处理机制,包括 Result 和 O…...

程序与进程 linux系统

程序与进程 程序 &#xff08; program &#xff09;&#xff1a; 通常为 binary program &#xff0c;放置在储存媒体中&#xff08;如硬盘、光盘、软盘、磁带等&#xff09;&#xff0c; 为实体文件的型态存在&#xff1b;二进制文件&#xff0c;比如静态 /bin/date…...

使用MongoDB构建AI:Story Tools Studio将生成式AI引入Myth Maker AI游戏

Story Tools Studio利用先进的生成式AI技术&#xff0c;打造沉浸式、个性化、无穷尽的情景体验。 Story Tools Studio创始人兼首席执行官Roy Altman表示&#xff1a;“我们的旗舰游戏Myth Maker AI采用的是我们自主研发的、以AI为驱动的专家指导型故事生成器MUSE&#xff0c;它…...

鸿蒙UIAbility组件概述(二)

鸿蒙UIAbility组件概述 UIAbility组件基本用法指定UIAbility的启动页面获取UIAbility的上下文信息 UIAbility组件与UI的数据同步使用EventHub进行数据通信使用AppStorage/LocalStorage进行数据同步 UIAbility组件间交互&#xff08;设备内&#xff09;启动应用内的UIAbility启动…...

Oracle(70)如何优化SQL查询?

优化SQL查询是数据库管理的重要部分&#xff0c;旨在提高查询性能&#xff0c;减少响应时间和资源消耗。以下是一些常见的SQL查询优化技术&#xff0c;结合代码示例详细说明。 1. 使用索引 索引是优化查询性能的最常见方法之一。索引可以显著减少数据检索的时间。 示例 假设…...

深度剖析:Jenkins构建任务无法中断的原因及解决方案

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…...

【YOLO】常用脚本

目录 VOC转YOLO划分训练集、测试集与验证集 VOC转YOLO import os import xml.etree.ElementTree as ETdef convert(size, box):dw 1. / size[0]dh 1. / size[1]x (box[0] box[1]) / 2.0y (box[2] box[3]) / 2.0w box[1] - box[0]h box[3] - box[2]x x * dww w * dwy…...

Springboot IOC DI理解及实现+JUnit的引入+参数配置

一、JavaConfig 我们通常使用 Spring 都会使用 XML 配置&#xff0c;随着功能以及业务逻辑的日益复杂&#xff0c;应用伴随着大量的 XML 配置文件以及复杂的 bean 依赖关系&#xff0c;使用起来很不方便。 在 Spring 3.0 开始&#xff0c;Spring 官方就已经开始推荐使用 Java…...

CeresPCL 最小二乘插值(曲线拟合)

一、简介 在多项式插值时,当数据点个数较多时,插值会导致多项式曲线阶数过高,带来不稳定因素。因此我们可以通过固定幂基函数的最高次数 m(m < n),来对我们要拟合的曲线进行降阶。之前的函数形式就可以变为: 既然是最小二乘问题,那么就仍然可以使用Ceres来进行求解。 …...

【TCP/IP】自定义应用层协议,常见端口号

互联网中&#xff0c;主流的是 TCP/IP 五层协议 5G/4G 上网&#xff0c;是有自己的协议栈&#xff0c;要比 TCP/IP 更复杂&#xff08;能够把 TCP/IP 的一部分内容给包含进去了&#xff09; 应用层 可以代表我们所编写的应用程序&#xff0c;只要应用程序里面用到了网络通信…...

Frida 的下载和安装

首先要安装好 python 环境 安装 frida 和 工具包 pip install frida frida-tools 查看版本&#xff1a; frida --version 16.4.8 然后到 github 上下载对应 server &#xff08; 和frida 的版本一致 16.4.8&#xff09; Releases frida/frida (github.com) 查看手机或…...