TTS-Web-Vue系列:Vue3实现内嵌iframe文档显示功能
🖼️ 本文是TTS-Web-Vue系列的新篇章,重点介绍如何在Vue3项目中优雅地实现内嵌iframe功能,用于加载外部文档内容。通过Vue3的响应式系统和组件化设计,我们实现了一个功能完善、用户体验友好的文档嵌入方案,包括加载状态管理、错误处理和自适应布局等关键功能。
📖 系列文章导航
欢迎查看主页
🌟 内嵌iframe的应用场景与价值
在现代Web应用中,内嵌iframe是集成外部内容的有效方式,特别适用于以下场景:
- 展示项目文档:直接嵌入项目文档网站,避免用户在多个标签页切换
- 整合第三方内容:无需重新开发,直接复用已有的Web资源
- 隔离运行环境:为外部内容提供独立的执行环境,避免与主应用冲突
- 保持UI一致性:让外部内容看起来像是应用的一部分,提升用户体验
- 降低开发成本:避免重复开发相似功能,专注于核心业务逻辑
在TTS-Web-Vue项目中,我们使用内嵌iframe来加载项目文档,使用户能够在不离开应用的情况下查阅使用指南、API文档和其他参考资料。
💡 实现思路与技术选型
整体设计方案
我们的iframe嵌入方案采用了以下设计思路:
- 响应式状态管理:使用Vue3的响应式系统管理iframe的加载状态
- 异常处理机制:完善的错误处理和恢复策略,提供友好的错误界面
- 动态样式调整:根据内容和容器大小动态调整iframe尺寸
- 跨域安全处理:合理设置sandbox属性和referrer策略,确保安全性
- 加载状态反馈:提供视觉反馈,优化用户等待体验
- 备用方案支持:支持多个文档源,在主源不可用时提供备选链接
这种方案既保证了功能的完整性,又提供了良好的用户体验和可维护性。
技术实现要点
- 使用Vue3的
ref
和watch
实现响应式状态管理 - 通过DOM API动态调整iframe样式和容器布局
- 利用Element Plus组件库提供加载和错误界面
- 使用PostMessage API实现iframe与主应用的通信
- 结合CSS动画提升加载体验
🧩 核心代码实现
主组件模板代码
在Main.vue中,我们实现了文档页面容器和iframe的基本结构:
<div v-if="page.asideIndex === '4'" class="doc-page-container" :key="'doc-page'"><!-- 加载状态显示 --><div v-if="!iframeLoaded && !iframeError" class="iframe-loading"><div class="loading-spinner"></div><p>正在加载文档<span class="loading-dots"></span></p></div><!-- iframe组件 --><iframe ref="docIframe"class="doc-frame" :src="iframeCurrentSrc" @load="handleIframeLoad"@error="handleIframeError"allow="fullscreen"referrerpolicy="no-referrer":class="{'iframe-visible': iframeLoaded}"sandbox="allow-scripts allow-same-origin allow-popups allow-forms"></iframe><!-- 错误状态显示 --><div v-if="iframeError" class="iframe-error"><el-icon class="error-icon"><WarningFilled /></el-icon><p>加载文档失败,请检查网络连接或尝试备用链接。</p><div class="error-actions"><el-button type="primary" @click="reloadIframe"><el-icon><RefreshRight /></el-icon> 重新加载</el-button><el-button @click="tryAlternativeUrl"><el-icon><SwitchButton /></el-icon> 尝试备用链接</el-button></div></div>
</div>
状态管理与初始化
在组合式API中管理iframe相关的状态:
// 声明状态变量
const docIframe = ref(null);
const iframeLoaded = ref(false);
const iframeError = ref(false);
const docUrl = ref('https://docs.tts88.top/');
const urlIndex = ref(0);
const iframeCurrentSrc = ref('');
const docUrls = ['https://docs.tts88.top/',// 可以添加备用链接
];// iframe初始化函数
const initIframe = () => {iframeCurrentSrc.value = '';// 在清除src后,立即设置容器和iframe样式以确保正确显示nextTick(() => {// 修改页面主容器样式,保留基本结构但减少内边距const mainContainer = document.querySelector('.modern-main');if (mainContainer instanceof HTMLElement && page?.value?.asideIndex === '4') {mainContainer.style.padding = '0';mainContainer.style.gap = '0';}const container = document.querySelector('.doc-page-container');if (container instanceof HTMLElement) {// 设置文档容器填充可用空间,但不使用fixed定位container.style.display = 'flex';container.style.flexDirection = 'column';container.style.height = 'calc(100vh - 40px)'; // 只预留顶部导航栏的空间container.style.margin = '0';container.style.padding = '0';container.style.borderRadius = '0';container.style.boxShadow = 'none';container.style.position = 'relative';}if (docIframe.value) {docIframe.value.style.display = 'block';docIframe.value.style.flex = '1';docIframe.value.style.width = '100%';docIframe.value.style.height = '100%';docIframe.value.style.minHeight = '700px';docIframe.value.style.maxHeight = 'none';docIframe.value.style.margin = '0';docIframe.value.style.padding = '0';docIframe.value.style.border = 'none';docIframe.value.style.borderRadius = '0';}// 设置iframe源iframeCurrentSrc.value = docUrl.value;console.log('iframe 初始化源设置为:', docUrl.value);});
};
事件处理函数
处理iframe的加载和错误事件:
// 处理 iframe 加载成功
const handleIframeLoad = (event) => {console.log('iframe 加载事件触发');// 检查iframe是否完全加载且可访问try {const iframe = event.target;// 不是所有iframe都会触发跨域报错,但我们需要检查是否实际加载成功if (iframe.contentWindow && iframe.src.includes(docUrl.value)) {iframeLoaded.value = true;iframeError.value = false;console.log('iframe 加载成功:', {width: iframe.offsetWidth,height: iframe.offsetHeight});// 尝试调整iframe高度nextTick(() => {adjustIframeHeight();// 发送初始化消息到iframesendInitMessageToIframe();});// 显示加载成功提示ElMessage({message: "文档加载成功",type: "success",duration: 2000,});} else {console.warn('iframe可能加载不完整或存在跨域问题');}} catch (error) {// 处理跨域安全限制导致的错误console.error('检查iframe出错 (可能是跨域问题):', error);// 我们不将这种情况标记为错误,因为iframe可能仍然正常加载iframeLoaded.value = true;}
};// 处理 iframe 加载失败
const handleIframeError = (event) => {console.error('iframe 加载失败:', event);iframeLoaded.value = false;iframeError.value = true;ElMessage({message: "文档加载失败,请检查网络连接",type: "error",duration: 3000,});
};// 重新加载 iframe
const reloadIframe = () => {console.log('重新加载 iframe');iframeLoaded.value = false;iframeError.value = false;// 强制 iframe 重新加载initIframe();ElMessage({message: "正在重新加载文档",type: "info",duration: 2000,});
};// 尝试使用备用链接
const tryAlternativeUrl = () => {urlIndex.value = (urlIndex.value + 1) % docUrls.length;docUrl.value = docUrls[urlIndex.value];console.log(`尝试备用文档链接: ${docUrl.value}`);iframeLoaded.value = false;iframeError.value = false;// 清空并重新设置src以确保重新加载initIframe();ElMessage({message: `正在尝试备用链接: ${docUrl.value}`,type: "info",duration: 3000,});
};
样式和动画设计
为iframe相关组件添加样式:
.iframe-loading, .iframe-error {position: absolute;top: 0;left: 0;right: 0;bottom: 0;display: flex;flex-direction: column;justify-content: center;align-items: center;background-color: var(--card-background);z-index: 1000;text-align: center;
}.iframe-loading {font-size: 18px;font-weight: 600;color: var(--text-primary);
}.loading-spinner {width: 40px;height: 40px;border: 4px solid rgba(74, 108, 247, 0.2);border-radius: 50%;border-top-color: var(--primary-color);animation: spin 1s linear infinite;margin-bottom: 16px;
}@keyframes spin {to {transform: rotate(360deg);}
}.iframe-error {padding: 30px;background-color: var(--card-background);
}.iframe-error p {margin: 16px 0;font-size: 16px;color: var(--text-secondary);
}.error-icon {font-size: 48px;color: #ff4757;margin-bottom: 16px;
}.error-actions {display: flex;gap: 16px;margin-top: 16px;
}.loading-dots {display: inline-block;width: 30px;text-align: left;
}.loading-dots:after {content: '.';animation: dots 1.5s steps(5, end) infinite;
}@keyframes dots {0%, 20% {content: '.';}40% {content: '..';}60% {content: '...';}80%, 100% {content: '';}
}
🔄 跨域通信实现
发送消息到iframe
通过postMessage API实现与iframe内容的通信:
// 向iframe发送消息
const sendMessageToIframe = (message) => {if (docIframe.value && docIframe.value.contentWindow) {try {docIframe.value.contentWindow.postMessage(message, '*');console.log('向iframe发送消息:', message);} catch (error) {console.error('向iframe发送消息失败:', error);}}
};// 在iframe加载完成后发送初始化消息
const sendInitMessageToIframe = () => {// 等待iframe完全加载setTimeout(() => {sendMessageToIframe({type: 'init',appInfo: {name: 'TTS Web Vue',version: '1.0',theme: document.body.classList.contains('dark-theme') ? 'dark' : 'light'}});}, 1000);
};
接收来自iframe的消息
监听并处理iframe发送的消息:
// 处理来自iframe的消息
const handleIframeMessage = (event) => {console.log('收到消息:', event);// 确保消息来源安全,验证来源域名const isValidOrigin = docUrls.some(url => {try {const urlHost = new URL(url).hostname;return event.origin.includes(urlHost);} catch (e) {return false;}});// 如果消息来源不安全,忽略此消息if (!isValidOrigin) {console.warn('收到来自未知来源的消息,已忽略:', event.origin);return;}console.log('来自文档页面的消息:', event.data);// 处理不同类型的消息if (typeof event.data === 'object' && event.data !== null) {// 文档加载完成消息if (event.data.type === 'docLoaded') {iframeLoaded.value = true;iframeError.value = false;ElMessage({message: "文档页面已准备就绪",type: "success",duration: 2000,});// 对iframe内容回送确认消息sendMessageToIframe({type: 'docLoadedConfirm',status: 'success'});}// 调整高度消息if (event.data.type === 'resizeHeight' && typeof event.data.height === 'number') {const height = event.data.height;if (height > 0 && docIframe.value) {// 确保高度合理const safeHeight = Math.max(Math.min(height, 5000), 300);docIframe.value.style.height = `${safeHeight}px`;console.log(`根据iframe请求调整高度: ${safeHeight}px`);}}}
};// 在组件挂载时添加消息监听器
onMounted(() => {window.addEventListener('message', handleIframeMessage);
});// 在组件卸载时移除监听器
onUnmounted(() => {window.removeEventListener('message', handleIframeMessage);
});
📱 自适应布局实现
响应式高度调整
动态调整iframe高度以适应不同屏幕尺寸:
// 添加新函数用于调整iframe高度
const adjustIframeHeight = () => {if (!docIframe.value) return;// 获取容器高度const container = document.querySelector('.doc-page-container');if (!container) return;// 修改页面主容器样式,减少内边距但保留基本布局const mainContainer = document.querySelector('.modern-main');if (mainContainer instanceof HTMLElement && page?.value?.asideIndex === '4') {mainContainer.style.padding = '0';mainContainer.style.gap = '0';}// 获取可用高度(视口高度减去顶部导航栏高度)const availableHeight = window.innerHeight - 40;// 设置container样式以充分利用可用空间if (container instanceof HTMLElement) {container.style.height = `${availableHeight}px`;container.style.maxHeight = `${availableHeight}px`;container.style.margin = '0';container.style.padding = '0';container.style.borderRadius = '0';container.style.boxShadow = 'none';container.style.position = 'relative';}// 设置iframe样式以充满容器docIframe.value.style.width = '100%';docIframe.value.style.height = '100%';docIframe.value.style.minHeight = '700px';docIframe.value.style.maxHeight = 'none';docIframe.value.style.display = 'block';docIframe.value.style.flex = '1';docIframe.value.style.margin = '0';docIframe.value.style.padding = '0';docIframe.value.style.border = 'none';docIframe.value.style.borderRadius = '0';
};// 监听窗口大小变化事件
const handleResize = () => {if (page?.value?.asideIndex === '4' && iframeLoaded.value) {adjustIframeHeight();}
};// 在组件挂载和窗口大小变化时调整高度
onMounted(() => {window.addEventListener('resize', handleResize);
});onUnmounted(() => {window.removeEventListener('resize', handleResize);
});
移动端显示优化
为移动设备添加特定的样式调整:
@media (max-width: 768px) {.doc-page-container {height: calc(100vh - 50px) !important; /* 为移动端顶部导航栏留出更多空间 */}.iframe-loading p, .iframe-error p {font-size: 14px;padding: 0 20px;}.error-actions {flex-direction: column;width: 80%;}.loading-spinner {width: 30px;height: 30px;}
}
🔒 安全性考虑
iframe安全属性设置
为确保iframe的安全性,我们设置了以下关键属性:
<iframe ref="docIframe"class="doc-frame" :src="iframeCurrentSrc" @load="handleIframeLoad"@error="handleIframeError"allow="fullscreen"referrerpolicy="no-referrer":class="{'iframe-visible': iframeLoaded}"sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
>
</iframe>
主要安全措施包括:
-
sandbox属性:限制iframe内容的权限,仅允许必要的功能
allow-scripts
: 允许运行脚本allow-same-origin
: 允许访问同源资源allow-popups
: 允许打开新窗口allow-forms
: 允许表单提交
-
referrerpolicy:设置为
no-referrer
防止泄露引用信息 -
消息验证:验证接收消息的来源,防止恶意站点发送的消息
跨域消息验证
在处理iframe消息时进行来源验证:
// 确保消息来源安全,验证来源域名
const isValidOrigin = docUrls.some(url => {try {const urlHost = new URL(url).hostname;return event.origin.includes(urlHost);} catch (e) {return false;}
});// 如果消息来源不安全,忽略此消息
if (!isValidOrigin) {console.warn('收到来自未知来源的消息,已忽略:', event.origin);return;
}
🎭 用户体验增强
加载状态优化
为提供更好的视觉反馈,我们添加了加载动画和进度指示:
<div v-if="!iframeLoaded && !iframeError" class="iframe-loading"><div class="loading-spinner"></div><p>正在加载文档<span class="loading-dots"></span></p>
</div>
动画效果通过CSS实现:
.loading-spinner {width: 40px;height: 40px;border: 4px solid rgba(74, 108, 247, 0.2);border-radius: 50%;border-top-color: var(--primary-color);animation: spin 1s linear infinite;margin-bottom: 16px;
}@keyframes spin {to {transform: rotate(360deg);}
}.loading-dots:after {content: '.';animation: dots 1.5s steps(5, end) infinite;
}@keyframes dots {0%, 20% {content: '.';}40% {content: '..';}60% {content: '...';}80%, 100% {content: '';}
}
错误处理与恢复
提供直观的错误界面和恢复选项:
<div v-if="iframeError" class="iframe-error"><el-icon class="error-icon"><WarningFilled /></el-icon><p>加载文档失败,请检查网络连接或尝试备用链接。</p><div class="error-actions"><el-button type="primary" @click="reloadIframe"><el-icon><RefreshRight /></el-icon> 重新加载</el-button><el-button @click="tryAlternativeUrl"><el-icon><SwitchButton /></el-icon> 尝试备用链接</el-button></div>
</div>
📊 性能优化
减少重绘和回流
为提高iframe加载性能,我们采取了以下优化措施:
// 先将iframe的src设为空,然后再设置目标URL,减少重复加载
iframeCurrentSrc.value = '';// 使用nextTick等待DOM更新后再进行样式调整
nextTick(() => {// 样式调整代码...// 最后再设置srciframeCurrentSrc.value = docUrl.value;
});
延迟加载与可见性优化
只有在iframe加载完成后才显示内容,避免闪烁:
<iframe :class="{'iframe-visible': iframeLoaded}"<!-- 其他属性... -->
>
</iframe>
.doc-frame {opacity: 0;transition: opacity 0.3s ease;
}.iframe-visible {opacity: 1;
}
📝 总结与拓展
主要成果
通过Vue3实现内嵌iframe,我们为TTS-Web-Vue项目带来了以下价值:
- 一体化用户体验:用户无需离开应用即可访问文档
- 响应式布局:自适应不同屏幕尺寸,优化移动端体验
- 完善的状态管理:处理加载、错误等各种状态,提升用户体验
- 安全可控:通过sandbox和消息验证确保安全性
- 高性能:优化加载过程,减少性能开销
未来可能的拓展方向
- 内容预加载:实现文档预加载,进一步提升加载速度
- 深度链接:支持直接链接到文档的特定部分
- 离线支持:加入文档缓存功能,支持离线访问
- 内容同步:实现iframe内容与应用状态的双向同步
- 多文档管理:支持多个文档源和文档切换功能
🔗 相关链接
- TTS-Web-Vue项目主页
- 在线演示
- Vue3官方文档
- Element Plus UI库
- MDN iframe文档
注意:本文介绍的功能仅供学习和个人使用,请勿用于商业用途。如有问题或建议,欢迎在评论区讨论!
相关文章:
TTS-Web-Vue系列:Vue3实现内嵌iframe文档显示功能
🖼️ 本文是TTS-Web-Vue系列的新篇章,重点介绍如何在Vue3项目中优雅地实现内嵌iframe功能,用于加载外部文档内容。通过Vue3的响应式系统和组件化设计,我们实现了一个功能完善、用户体验友好的文档嵌入方案,包括加载状态…...
AWS CloudTrail日志跟踪启用
问题 启用日志管理。 步骤 审计界面,如下图: 点击创建跟踪,AWS云就会记录AWS账号在云中的操作。...
PHP 编程:现代 Web 开发的基石与演进
引言 PHP(Hypertext Preprocessor)自1995年诞生以来,已成为全球最流行的服务器端脚本语言之一。尽管近年来Node.js、Python等语言在特定领域崭露头角,但PHP仍占据着超过78%的网站市场份额(W3Techs数据)。本…...
NAT/代理服务器/内网穿透
目录 一 NAT技术 二 内网穿透/内网打洞 三 代理服务器 一 NAT技术 跨网络传输的时候,私网不能直接访问公网,就引入了NAT能讲私网转换为公网进行访问,主要解决IPv4(2^32)地址不足的问题。 1. NAT原理 当某个内网想访问公网,就必…...
[已解决] VS Code / Cursor / Trae 的 PowerShell 终端 conda activate 进不去环境的常见问题
背景 PS C:\Users\Lenovo\WPSDrive\669715199_3\WPS云盘\课程\研一\ROAS5700 Robot Motion Planning and Control\Final\LaTex报告\final-v1> conda activate mpPS C:\Users\Lenovo\WPSDrive\669715199_3\WPS云盘\课程\研一\ROAS5700 Robot Motion Planning and Control\Fin…...
Kuka AI音乐AI音乐开发「人声伴奏分离」 —— 「Kuka Api系列|中文咬字清晰|AI音乐API」第6篇
导读 今天我们来了解一下 Kuka API 的人声与伴奏分离功能。 所谓“人声伴奏分离”,顾名思义,就是将一段完整的音频拆分为两个独立的轨道:一个是人声部分,另一个是伴奏(乐器)部分。 这个功能在音乐创作和…...
深度伪造对知识产权保护的新挑战与应对之策
首席数据官高鹏律师团队 在科技的飞速发展带来了诸多便利的同时,也引发了一系列复杂的法律问题,其中深度伪造技术对知识产权保护的冲击尤为显著,亟待引起广泛关注与深入探讨。 深度伪造,简单来说,是借助先进的人工智…...
【嵌入式开发-软件定时器】
嵌入式开发-软件定时器 ■ 1.■ 2.■ 3.■ 4. ■ 1. ■ 2. ■ 3. ■ 4....
3天重庆和成都旅游规划
重庆和成都都是大城市,各自都有丰富的旅游资源。如果要在三天内两头都游览,可能需要合理安排时间,确保既能体验到重庆的特色,又能在成都游览主要景点。然而,考虑到交通时间,如果从重庆到成都需要一定的时间…...
JAVA中的文件操作
文章目录 一、文件认识(一)文件的分类(二)目录结构 二、文件操作(一)File类1.属性2.构造方法3.方法 (二)File类的具体使用1.文件路径的查看2.文件的基本操作(1࿰…...
深度解析网闸策略:构建坚固的网络安全防线
深度解析网闸策略:构建坚固的网络安全防线 在数字化浪潮中,网络安全已成为企业、机构乃至国家稳定发展的关键要素。随着网络攻击手段日益复杂多样,传统的网络安全防护措施难以满足日益增长的安全需求。网闸作为一种先进的网络安全设备&#x…...
【Rust trait特质】如何在Rust中使用trait特质,全面解析与应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
滑动窗口算法笔记
力扣209 题目分析:想象一个窗口遍历着这个数组,不断扩大右边界,让r。往窗口中添加数字: 此时我们找到了这个窗口,它的和满足了大于等于target的条件,题目让我求最短的,那么我们就尝试来缩短它&…...
Problem A: 歌手打分
1.题目描述 在歌唱比赛中,共有10位评委进行打分,在计算歌手得分时,去掉一个最高分,去掉一个最低分,然后剩余的8位评委的分数进行平均,就是该选手的最终得分。输入每个评委的评分,求某选手的得分…...
容器安全-核心概述
文章摘要 本文探讨了容器安全的四个核心类别,包括环境基础设施安全、镜像安全、运行时安全和生态安全。尽管 EDR 能提供主机安全层面的部分防护,但无法覆盖容器的镜像安全和生态安全。容器的镜像安全和生态安全问题,如镜像漏洞、恶意镜像、容…...
Golang实践录:在go中使用curl实现https请求
之前曾经在一个 golang 工程调用 libcur 实现 https的请求,当前自测是通过的。后来迁移到另一个小系统出现段错误,于是对该模块代码改造,并再次自测。 问题提出 大约2年前,在某golang项目使用libcurl进行https请求(参…...
nvrtc环境依赖
一 下载 1.1 添加nvidia的源(不同于pypi) pip install nvidia-pyindex 1.2 pip dowload 执行 pip download nvidia-cuda-runtime nvidia-cuda-python 会发现文件夹多了以下几个文件 而需要安装的则只有红框的三个文件, 二 安装 对红框的…...
【计算机视觉】OpenCV实战项目:GraspPicture 项目深度解析:基于图像分割的抓取点检测系统
GraspPicture 项目深度解析:基于图像分割的抓取点检测系统 一、项目概述项目特点 二、项目运行方式与执行步骤(一)环境准备(二)项目结构(三)执行步骤 三、重要逻辑代码解析(一&#…...
Redis持久化存储
我们知道Redis是将数据放在内存中的,那怎么做到持久化存储呢?很简单,就是内存存一份,硬盘也存一份.那么两个地方都存会不会影响效率?答案是影响是不大的,要看具体的策略.同时也要注意内存的数据和硬盘中的数据可能会有一点不同.这也是取决于策略的不同. Redis持久化存储的两个…...
网络检测工具InternetTest v8.9.1.2504 单文件版,支持一键查询IP/DNS、WIFI密码信息
—————【下 载 地 址】——————— 【本章下载一】:https://drive.uc.cn/s/295e068b79314 【本章下载二】:https://pan.xunlei.com/s/VOQDXguH0DYPxrql5y2zlkhTA1?pwdg2nx# 【百款黑科技】:https://ucnygalh6wle.feishu.cn/wiki/…...
elpis-core: 基于 Koa 实现 web 服务引擎架构设计解析
前言 内容来源于抖音【哲玄前端】大佬的《大前端全栈实践》课程,此课程是从零开始做一个企业级的全栈应用框架。此框架是基于koa.js构建的服务引擎,对BFF层的框架封装,让我感受颇深。 整体elpis项目架构设计 elpis-core设计思路 可以看到elpi…...
计算机网络-MPLS LDP基础实验配置
前面我们学习了LDP的会话建立、标签发布与交换、LDP的工作原理,今天通过一个基础实验来加深记忆。 一、LDP基础实验 实验拓扑: 1、IGP使用OSPF进行通告,使用Lookback接口作为LSR ID,LDP ID自动生成。 2、实验目的:使…...
搜索二维矩阵 II
存储m和n,用i表示行,j表示列,i从最后一行开始遍历,j从0开始遍历,当前值比目标值小j,反之i-- class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int…...
C++中如何实现一个单例模式?
单利模式是指对象在整个程序中只有一个实例,提供一个访问方法供全局访问。实现单例模式有如下要求: 1.私有化构造函数:将构造函数定义为私有,以防外部通过构造函数创建其它实例。 2.静态实例:在内部提供一个静态实例…...
进程与线程
进程与线程:计算机世界的"公司与员工" 进程与线程的本质区别 进程(Process)是计算机中独立运行的程序实例,拥有自己的内存空间和系统资源;而线程(Thread)是进程内的执行单元,共享所属进程的资源,但拥有独立的执行路径。 🏢 生活类比:想象一个大型企业的运…...
JDK 命令行工具大全与学习方法总结 —— 从帮助文档到高效实践
JDK 命令行工具大全与学习方法总结 —— 从帮助文档到高效实践 Java开发与运维过程中,JDK自带的命令行工具是定位问题、性能调优、编译调试的基石。本文全面梳理JDK常用命令工具、帮助文档的获取方式,并总结类似Linux命令行的学习方法,助你系…...
行业趋势与技术创新:驾驭工业元宇宙与绿色智能制造
引言 制造业发展的新格局:创新势在必行 当今制造业正经历深刻变革,面临着供应链波动、个性化需求增长、可持续发展压力以及技能人才短缺等多重挑战。在这样的背景下,技术创新不再是可有可无的选项,而是企业保持竞争力、实现可持…...
代码随想录算法训练营第三十九天(打家劫舍专题) | 198.打家劫舍、213.打家劫舍II、337.打家劫舍III
一、198.打家劫舍 题目链接:198. 打家劫舍 - 力扣(LeetCode) 文章讲解:代码随想录 视频讲解:动态规划,偷不偷这个房间呢?| LeetCode:198.打家劫舍_哔哩哔哩_bilibili 1. 思路 大家如…...
Linux514 rsync 解决方案环境配置
节点ab都改为NAT模式 网关和VMnet8网卡不一致 ping 不通外网 ping不通外网 是这里的问题吗 怎么突然就ping通了 没改啥啊 上面改了dhcp范围后 ping还是ping不通 为啥现在又ping通了 设置节点b 推测应该是dhcp范围问题 今日源码 节点b MX...
STM32F103_LL库+寄存器学习笔记23 - PWM波形输出及软件方式调整周期与占空比
导言 脉宽调制(PWM)是 STM32 定时器最常用的输出模式之一,广泛应用于电机驱动、LED 调光、伺服控制和功率管理等场景。本篇文章将以 TIM5 为例,从寄存器层面深入剖析 PWM 输出的原理与实现步骤。通过本篇博客,你不仅能…...
Canvas知识框架
一、Canvas基础 核心概念 Canvas是位图绘图区域,通过JavaScript(或Python等)动态绘制图形。 坐标系:左上角为原点 (0, 0),x向右递增,y向下递增。 绘图流程: const canvas document.getElemen…...
【SSL证书系列】客户端如何验证https网站服务器发的证书是否由受信任的根证书签发机构签发
客户端验证HTTPS网站证书是否由受信任的根证书颁发机构(CA)签发,是一个多步骤的过程,涉及证书链验证、信任锚(Trust Anchor)检查、域名匹配和吊销状态验证等。以下是详细的验证流程: 1. 证书链的…...
spark小任务
import org.apache.spark.{Partitioner, SparkConf, SparkContext}object PartitionCustom {// 分区器决定哪一个元素进入某一个分区// 目标: 把10个分区器,偶数分在第一个分区,奇数分在第二个分区// 自定义分区器// 1. 创建一个类继承Partitioner// 2. …...
git push 报错:send-pack: unexpected disconnect while reading sideband packet
背景 新建了一个仓库,第一次push 代码文件,文件中有一个依赖的jar,有80MB,结果push的时候报错。 错误信息 error: RPC failed; HTTP 500 curl 22 The requested URL returned error: 500 send-pack: unexpected disconnect whi…...
读入csv文件写入MySQL
### 使用 Spark RDD 读取 CSV 文件并写入 MySQL 的实现方法 #### 1. 环境准备 在使用 Spark 读取 CSV 文件并写入 MySQL 数据库之前,需要确保以下环境已配置完成: - 添加 Maven 依赖项以支持 JDBC 连接。 - 配置 MySQL 数据库连接参数,包括 …...
5.18-AI分析师
强化练习1 神经网络训练案例(SG) #划分数据集 #以下5行需要背 folder datasets.ImageFolder(rootC:/水果种类智能训练/水果图片, transformtrans_compose) n len(folder) n1 int(n*0.8) n2 n-n1 train, test random_split(folder, [n1, n2]) #训…...
腾讯云运营开发 golang一面
redis为什么单线程会快 每秒10w吞吐量 io多路复用 一个文件描述符整体拷贝;调用epoll_ctl 单个传递 内核遍历文件描述符判断是否有事件发送;回调函数列表维护 修改有事件发送的socket为可读或可写,返回整个文件描述符;返回链…...
spark数据压缩
### Spark 数据压缩方法及其实现 在大数据处理框架中,数据压缩是一个重要的环节,它不仅能够减少磁盘占用空间,还能降低网络传输成本。然而,在分布式计算环境中(如 Spark),选择合适的压缩编解码…...
synchronized关键字详解
synchronized关键字详解 1. 基本概念与使用方式 作用:确保多个线程在访问共享资源时的互斥性,防止数据不一致。使用方式: 修饰实例方法:锁对象为当前实例(this)。public synchronized void instanceMethod() {// 同步代码 }修饰静态方法:锁对象为类的Class对象。public…...
React useState 的同步/异步行为及设计原理解析
一、useState 的同步/异步行为 异步更新(默认行为) • 场景:在 React 合成事件(如 onClick)或生命周期钩子(如 useEffect)中调用 useState 的更新函数时,React 会将这些更新放入队列…...
《社交应用动态表情:RN与Flutter实战解码》
React Native依托于JavaScript和React,为动态表情的实现开辟了一条独特的道路。其核心优势在于对原生模块的便捷调用,这为动态表情的展示和交互提供了强大支持。在社交应用中,当用户点击发送动态表情时,React Native能够迅速调用相…...
【Oracle专栏】清理告警日志、监听日志
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 今天在导入数据库时,发现之前可以导入,今天导入时居然报空间不足,于是检查是哪里占用空间比较大。检查回收站、归档日志,发现没有。然后检查告警日志、监听日志,发现果然占用空间比较大,于是进行…...
Ubuntu24.04编译ORB_SLAM的一系列报错解决
Ubuntu24.04编译ORB_SLAM的一系列报错解决 decay_t报错 报错信息:error: ‘decay_t’ is not a member of ‘std’;did you mean ‘decay’ 将CMakeLists.txt中第17行的c标准修改为c14即可: 修改前: CHECK_CXX_COMPILER_FLAG…...
Python × CARLA:如何在自动驾驶仿真世界里打造智能驾驶系统?
Python CARLA:如何在自动驾驶仿真世界里打造智能驾驶系统? 在人工智能与自动驾驶的浪潮中,真实世界的测试成本高昂,而自动驾驶仿真已成为开发者训练和测试 AI 驾驶算法的关键技术手段。其中,CARLA(Car Learning to Act)作为开源自动驾驶仿真平台,凭借其真实感强、高度…...
如何迁移 WSL 卸载 Ubuntu WSL
迁移 WSL 到其他盘区 假设您已经安装了 WSL 上的 Ubuntu 22.04 LTS,并且想要将其从 C 盘迁移到 D 盘。 查看 WSL 状态: 打开 PowerShell 或 CMD,运行以下命令查看当前安装的 WSL 发行版: wsl -l -v假设输出显示 Ubuntu-22.04 正在…...
【Linux】多路转接epoll、Linux高并发I/O多路复用
📚 博主的专栏 🐧 Linux | 🖥️ C | 📊 数据结构 | 💡C 算法 | 🅒 C 语言 | 🌐 计算机网络 上篇文章:五种IO模型与阻塞IO以及多路转接select机制编写echoserver 下篇文章…...
【taro3 + vue3 + webpack4】在微信小程序中的请求封装及使用
前言 正在写一个 以taro3 vue3 webpack4为基础框架的微信小程序,之前一直没有记咋写的,现在总结记录一下。uniapp vite 的后面出。 文章目录 前言一、创建环境配置文件二、 配置 Taro 环境变量三、 创建请求封装四、如何上传到微信小程序体验版1.第二…...
在python中使用Json提取数据
文章目录 一、前言二、格式转换2.1 dumps函数2.2 loads函数2.3 错误处理 三、JSONPath模块四、JMESPath模块4.1 search函数4.2 基本语法4.2.1 基本查询4.2.2 投影4.2.3 管道4.2.4 多选4.2.5 函数 一、前言 官方文档:https://docs.python.org/zh-cn/3.12/library/js…...
备战菊厂笔试4
目录 39.组合总和 回溯(单向剪枝) 3102.最小化曼哈顿距离 利用曼哈顿距离的性质 3163.压缩字符串3 46.全排列 53.最大子数组和 39.组合总和 39. 组合总和 注意: set不能添加list得加元组 元组不可修改 sorted后得赋值 class So…...
白盒测试——基本路径测试法
一、实验名称 白盒测试——基本路径测试法 二、实验目的 白盒测试是结构测试,是依据被测程序的内部逻辑结构设计测试用例,驱动被测程序运行完成的测试,通过本实验希望: 1、掌握基本路径测试法的基本概念,用具体的例子…...