HarmonyOS:WebView 控制及 H5 原生交互实现
一、效果展示
二、技术栈
-
技术栈:
-
编程语言:使用 TypeScript 进行开发,借助其类型系统提升代码的可读性与稳定性。
-
框架与库:基于鸿蒙系统相关框架(如
@kit.ArkWeb
、@hadss/hmrouter
)进行开发,同时结合自定义的Index
模块(其中包含auth
、cameraPlugin
等)来实现特定业务功能。
-
-
核心点:
-
组件化开发:通过
@Component
装饰器定义MKWeb
组件,组件内封装了各种状态(如src
、title
等)和方法(如webBack
、webClose
等),使得代码结构清晰,易于维护。 -
WebView 集成:利用
webview.WebviewController
控制 WebView,实现页面加载、刷新、导航等功能,并通过一系列on
事件(如onPageBegin
、onProgressChange
等)监听 WebView 的状态变化,实时更新组件状态,为用户提供良好的交互体验。 -
H5 与原生交互:通过
controller.registerJavaScriptProxy
方法注册 JavaScript 代理,实现 H5 调用原生的用户信息查询、移除、更新以及相机相册调用等功能,打通了 H5 与原生应用的通信桥梁。 -
UI 构建:运用
@Builder
装饰器构建菜单和整体 UI 布局,使用Column
、Row
等布局组件实现页面的合理排版,同时通过Image
、Text
等组件展示界面元素,并且对Image
组件进行扩展定义通用的图标样式。
-
三、详细源码及注解
// 导入所需的模块和类
import { auth, cameraPlugin, MkUser, SafeConstants } from "../../../../Index"
import { webview } from "@kit.ArkWeb"
import { HMRouterMgr } from "@hadss/hmrouter"// 使用 @Component 装饰器定义一个组件
@Component
export struct MKWeb {// 定义加载的页面地址,初始值为空字符串src: ResourceStr = '' // 加载的页面地址// 定义当前网页的标题,初始值为 '美寇商城'@State title: string = 'XX商城'// 从本地存储中获取顶部安全距离,初始值为 0@StorageProp(SafeConstants.TOP_HEIGHT) safeTop: number = 0// 定义是否正在加载的状态,初始值为 true@State isLoading: boolean = true// 定义加载进度,初始值为 0@State Progress:number = 0// 定义当前页面在历史记录中的索引,初始值为 0@State historyCurrIndex: number = 0// 定义当前页面在历史记录中的总长度,初始值为 0@State historySize: number = 0// 创建一个 WebviewController 实例,用于控制 WebViewcontroller = new webview.WebviewController()/*** 回到web容器的上一个页面*/webBack(){// 如果当前页面在历史记录中有前一个页面,则返回上一个页面if(this.historyCurrIndex > 0){this.controller.backward()}else{// 否则,关闭当前页面HMRouterMgr.pop()}}/*** 回到上一个页面*/webClose(){// 关闭当前页面HMRouterMgr.pop()}/*** h5调用原生程序功能* */webInit(){// 注册 JavaScript 代理,允许 H5 调用原生功能this.controller.registerJavaScriptProxy({// 查询当前用户信息queryUser:():MkUser =>auth.getUser(),// 移除当前用户信息removeUser:():void =>auth.removeUser(),// 更新当前用户信息updateUser:(u:MkUser):void => auth.saveUser(u),// 调用相机拍照并返回照片路径pickerCamera:():Promise<string>=>cameraPlugin.pickerCamera(),// 调用相册选择照片并返回照片路径pickerPhoto:():Promise<string>=>cameraPlugin.pickerCamera()},'mk',['queryUser','removeUser','updateUser','pickerCamera','pickerPhoto'])}// 使用 @Builder 装饰器定义一个菜单构建器@BuilderMenuBuilder() {Menu() {// 添加一个菜单项,点击时刷新页面MenuItem({ content: '刷新一下' }).onClick(() => {this.controller.refresh()})}.width(100).fontColor($r('app.color.text')).font({ size: 14 }).radius(4)}// 构建组件的 UIbuild() {Column(){/*----------------------------------导航条--------------------------------------*/Row() {Row() {// 添加返回按钮,点击时调用 webBack 方法Image($r("app.media.ic_public_left")).iconStyle().onClick(() => {this.webBack()})// 添加关闭按钮,点击时调用 webClose 方法Image($r('app.media.ic_public_close')).iconStyle().onClick(() => {this.webClose()})}.width(100)// 显示当前网页的标题Text(this.title).fontSize(16).fontWeight(500).fontColor($r('app.color.black')).layoutWeight(1).maxLines(1).textAlign(TextAlign.Center).textOverflow({ overflow: TextOverflow.MARQUEE })Row() {Blank()// 添加更多操作按钮,绑定菜单Image($r('app.media.ic_public_more')).iconStyle().bindMenu(this.MenuBuilder)}.width(100)}.height(50 + this.safeTop).backgroundColor($r('app.color.white')).padding({ top: this.safeTop })/*---------------------------------堆叠布局-------------------------------------*/Stack({alignContent: Alignment.Top}) {// 如果正在加载,显示进度条if(this.isLoading){Progress({total: 100, value:this.Progress, type: ProgressType.Linear}).style({strokeWidth: 2,enableSmoothEffect: true}).color($r('app.color.red')).zIndex(1)}// 添加 WebView 组件,加载指定页面Web({ src:this.src, controller:this.controller })// 页面开始加载时,设置 isLoading 为 true.onPageBegin(()=>{this.isLoading = true})// 页面加载进度变化时,更新 Progress 状态.onProgressChange((res)=>{this.Progress = res.newProgress// 如果加载完成,延迟 300 毫秒后设置 isLoading 为 falseif(res.newProgress == 100){animateTo({duration: 300,delay:100}, ()=>{this.isLoading = false})}})// 页面加载完成时,不执行任何操作.onPageEnd(()=>{})// 刷新历史记录时,更新当前页面的历史记录索引和总长度.onRefreshAccessedHistory(()=>{const history = this.controller.getBackForwardEntries()this.historyCurrIndex = history.currentIndexthis.historySize = history.size})// 接收到页面标题时,更新 title 状态.onTitleReceive((res)=>{this.title = res.title})// 页面显示时,初始化 WebView.onAppear(()=>{this.webInit()})}.width('100%').layoutWeight(1)}.width('100%').height('100%').backgroundColor($r('app.color.under'))}
}// 扩展 Image 组件,定义图标样式
@Extend(Image)
function iconStyle() {.width(24).aspectRatio(1).fillColor($r('app.color.text')).margin(13)
}
Web组件主要完成混合开发单页面业务,在其中集成了Loading加载动画,以及注入了鸿蒙原生的功能(图库、调用相机,省市区,注:省市区是一个JSON文件通常存放在Rawfile文件下,我这里的JSON未放上啦,需要可以自己手动添加一下)
import { camera, cameraPicker } from "@kit.CameraKit";
import { fileIo } from "@kit.CoreFileKit";
import { util } from "@kit.ArkTS";class CameraPlugin {async pickerCamera(){// 1. 打开相机后置摄像头得到拍照结果集const pickerProfile: cameraPicker.PickerProfile = {// 后置摄像头cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK};// 打开相机const pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(getContext(),// 只允许选择图片[cameraPicker.PickerMediaType.PHOTO], pickerProfile);// 2. 根据结果集的URI属性同步打开文件const file = fileIo.openSync(pickerResult.resultUri)// 3. 同步读取文件的详情信息const stat = fileIo.statSync(file.fd)// 4. 定义缓冲区用于保存读取的文件const buffer = new ArrayBuffer(stat.size)// 5. 开始同步读取内容到缓冲区fileIo.readSync(file.fd, buffer)// 6. 读取完毕后关闭文件流fileIo.closeSync(file)// 7. 借助util工具方法把读取的文件流转成base64编码的字符串const helper = new util.Base64Helper()// 8. 把base64编码的字符串打印出来const str = helper.encodeToStringSync(new Uint8Array(buffer))// 9. 打印日志console.log('mk-logger', 'pickerCamera', str)return str}
}export const cameraPlugin = new CameraPlugin()
import { photoAccessHelper } from "@kit.MediaLibraryKit"
import { fileIo } from "@kit.CoreFileKit"
import { util } from "@kit.ArkTS"class PhotoPlugin{async pickPhoto(){// 1. 打开相册选择图片let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions()// 设置图片类型PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE// 设置最多可选图片数量PhotoSelectOptions.maxSelectNumber = 1// 设置是否显示原图let photoPicker = new photoAccessHelper.PhotoViewPicker()// 调用相册选择图片const res = await photoPicker.select(PhotoSelectOptions)// 2. 文件操作// 2.1 获取照片的uri地址const uri = res.photoUris[0]// 2.2 根据uri同步打开文件const file = fileIo.openSync(uri)// 2.3 同步获取文件的详细信息const stat = fileIo.statSync(file.fd)// 2.4 创建缓冲区存储读取的文件流const buffer = new ArrayBuffer(stat.size)// 2.5 开始同步读取文件流到缓冲区fileIo.readSync(file.fd, buffer)// 2.6 关闭文件流fileIo.closeSync(file)// 3. 转成base64编码的字符串const helper = new util.Base64Helper()const str = helper.encodeToStringSync(new Uint8Array(buffer))console.log('mk-logger', 'photoPlugin-str', str)return str}
}export const photoPlugin = new PhotoPlugin()
import { util } from '@kit.ArkTS'// 1. 定义读取的本地数据的数据类型(AreaDataItem)
export interface AreaDataItem {code: stringname: stringareaList: AreaDataItem[]
}// 2. 定义输出数据的数据类型(AreaColumns)
export interface AreaColumns {province_list: Record<number, string>city_list: Record<number, string>county_list: Record<number, string>
}class LocationPlugin {async getAreaColumns(){// 1. 定义对象用于存储转换后的数据const areaColumns: AreaColumns = {province_list: {},city_list: {},county_list: {}}try {// 2. 读取rawfile目录下的本地文件const unit8Array = getContext().resourceManager.getRawFileContentSync('area.json')// 3. 将读取的字节数组转成字符串const decoder = new util.TextDecoder()const resStr = decoder.decodeToString(unit8Array)// 4. 将读取的Json字符串转成对象数组const areaData = JSON.parse(resStr) as AreaDataItem[]// 5. 遍历处理数据// 5.1 省转换areaData.forEach((province)=>{areaColumns.province_list[Number(province.code)] = province.name// 5.2 市转换province.areaList.forEach((city)=>{areaColumns.city_list[Number(city.code)] = province.name// 5.3 区转换city.areaList.forEach((county)=>{areaColumns.county_list[Number(county.code)] = county.name})})})// 6. 返回数据AlertDialog.show({message:JSON.stringify(areaColumns,null,4)})return areaColumns} catch (e) {return areaColumns}}
}export const locationPlugin = new LocationPlugin()
四、总结
本篇代码主要围绕MKWeb
组件展开,综合运用多种技术实现了 Web 相关的丰富功能。从技术栈的选型到各功能模块的核心实现,都展示了在鸿蒙系统下开发 Web 交互界面的思路。然而,代码在一些细节上存在不足,如代码重复、错误处理缺失以及配置灵活性问题。通过对这些要点的分析,开发者可以在类似项目中优化代码结构,增强应用的健壮性和可维护性,从而打造出更优质的 Web 相关应用功能。有需要的可自行改造,这里这里只封装了原生的功能,但是调用相机需要真机,有条件可以自行尝试,这里的源码仅供参考,有其他的需求可以参考改造。
相关文章:
HarmonyOS:WebView 控制及 H5 原生交互实现
一、效果展示 二、技术栈 技术栈: 编程语言:使用 TypeScript 进行开发,借助其类型系统提升代码的可读性与稳定性。 框架与库:基于鸿蒙系统相关框架(如kit.ArkWeb、hadss/hmrouter)…...
250405-VSCode编辑launch.json实现Debug调试Open-WebUI
A. 最终效果 根据__init__.py配置launch.json 根据中utils/chat.py中form_data的messages [{role: user, content: 唐老鸭}],可以找到用户输入,进而通过关键词或模型调用的方式,对敏感问题进行特殊处理。 B. 文件配置 launch.json // { // /…...
SQL Server 数据库实验报告
1.1 实验题目:索引和数据完整性的使用 1.2 实验目的: (1)掌握SQL Server的资源管理器界面应用; (2)掌握索引的使用; (3)掌握数据完整性的…...
【寻找Linux的奥秘】第三章:基础开发工具(上)
请君浏览 前言1. 软件包管理器1.1 linux中安装软件1.2 yum的具体操作1.2.1 查找软件包1.2.2 安装软件1.2.3 卸载软件 1.3 小结 2. 编辑器vim2.1 vim的基本概念和操作2.2 命令模式的命令集光标定位其他命令模式切换(常用的) 2.3 末⾏模式的命令集2.4 小结…...
Photoshop 2025 Mac中文Ps图像编辑
Photoshop 2025 Mac中文Ps图像编辑 文章目录 Photoshop 2025 Mac中文Ps图像编辑一、介绍二、效果三、下载 一、介绍 Adobe Photoshop 2025 Mac版集成了多种强大的图像编辑、处理和创作功能。①强化了Adobe Sensei AI的应用,通过智能抠图、自动修复、图像生成等功能…...
#SVA语法滴水穿石# (004)关于 ended 和 triggered 用法
在 SystemVerilog 断言(SVA, SystemVerilog Assertions)中,ended 是一个用于 序列(sequence) 的关键字,它表示某个序列(sequence)在特定时间点已经成功匹配(即“结束”)。 ended 主要用于 同步不同序列的时间关系,尤其是在多序列组合或属性(property)中需要对齐时…...
16.1Linux自带的LED灯驱动实验(知识)_csdn
前面我们都是自己编写 LED 灯驱动,其实像 LED 灯这样非常基础的设备驱动, Linux 内核已经集成了。 Linux 内核的 LED 灯驱动采用 platform 框架,因此我们只需要按照要求在设备树文件中添加相应的 LED 节点即可,本章我们就来学习如…...
普通类、抽象类和接口的区别
1. 普通类 (Concrete Class) 定义:完整的类,可以直接实例化 特点: 可以包含属性、普通方法(有具体实现)和构造方法 可以被直接实例化创建对象 可以被继承(除非用final修饰) 示例࿱…...
使用 Elastic 实现端到端的大语言模型(LLM)可观测性:洞察生成式 AI 应用这个不透明的世界
作者:来自 Elastic Daniela Tzvetkova 及 Bahubali Shetti 在快速发展的人工智能领域,大语言模型(Large Language Models - LLMs)已成为创新的灯塔,为各行各业带来了前所未有的能力。从生成类人文本、翻译语言到提供个…...
15.2linux设备树下的platform驱动编写(程序)_csdn
我尽量讲的更详细,为了关注我的粉丝!!! 修改设备树文件: 这个我们在上一章已经写过了,但是还是带着大家来重写一遍! 1.打开pinctrl-stm32.c 这个文件: strict 成员变量默认为 true&…...
Java的Selenium的特殊元素操作与定位之window切换
当你要操作另外一个窗口页面的元素时,一定要注意先切换窗口 切换方式:传入要操作窗口的name或者句柄handle driver.switchTo.window(nameOrHandle); 如何获取到窗口的句柄 driver.getWindowHandle();//获取当前操作窗口的句柄driver.getWindowHandles();//获取测…...
【Rust学习】Rust环境搭建和Rust基础语法
本文专栏:Rust学习 目录 一,Rust环境搭建 1,C环境安装 2,Rust下载 3,Rust安装 4,Rust环境检测 二,创建Rust项目 1,rustc 2,cargo 三,输出到命令行 …...
在windows环境下通过docker-compose脚本自动创建mysql和redis
一、环境版本 在windows环境下通过docker容器运行各种服务,使用的软件版本如下: docker desktop :V4.39.0 【docker的安装环境设置略】 mysql:9.2 redis:7.4.2 二、各配置文件 1.已经解决了字符集和排序规则问题造成…...
【玩泰山派】2、制作buildroot镜像,并烧录
文章目录 前言制作buildroot镜像过程搭建环境(docker版)下载泰山派开发的sdk利用制作的镜像和下载的sdk去启动开发docker容器编译buildroot镜像 参考 前言 泰山派官方提供了不少现成的镜像 但是都买了泰山派了,肯定是想自己编译折腾下&…...
实验二 VLAN 的配置与应用
一、实验目的 1. 熟悉 VLAN 和 PORT VLAN 的原理; 2. 熟悉华为网络模拟器的使用; 3. 掌握网络拓扑图的绘制; 4. 掌握单交换机内 VLAN 的配置。 二、实验设备 PC、华为模拟器 ENSP。 三、实验步骤 知识准备:VLAN 和 PORT V…...
【C/C++算法】蓝桥杯之递归算法(如何编写想出递归写法)
绪论:冲击蓝桥杯一起加油!! 每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: ———————— 早关注不迷路,话不多说安全带系好,发车啦&am…...
coding ability 展开第九幕(位运算——进阶篇)超详细!!!!
文章目录 前言丢失的数字两整数之和只出现一次的数字II消失的两个数字总结 前言 上一篇博客,我们已经把位运算的基础知识,以及基本运算都掌握啦 上次的习题还是让人意犹未尽,今天我们来尝试一下难一点的题目 位运算熟练起来真的让人觉得做题是…...
Python实现NOA星雀优化算法优化随机森林回归模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 在现代数据科学领域,回归分析是解决预测问题的核心工具之一。然而,在面对复…...
蓝桥云客--浓缩咖啡液
4.浓缩咖啡液【算法赛】 - 蓝桥云课 问题描述 蓝桥杯备赛选手小蓝最近刷题刷到犯困,决定靠咖啡续命。他手上有 N 种浓缩咖啡液,浓度分别是 A1%, A2%, …, AN%,每种存货都是无限的。为了提神又不炸脑,小蓝需要按比例混合这…...
异常【C++】
文章目录 异常异常的概念和基本语法异常的三个关键字: 异常抛出和被接收的过程异常的再次抛出再次抛出被非catch(...)捕捉到的异常再次抛出被catch(...)捕捉到的异常 异常规范异常安全异常的优缺点优点缺点总结&#x…...
关于图片分类任务的猜想 | 撰写论文 paper
关于图片分类任务的猜想 | 撰写论文 paper 背景Yolo 是一次巨大的飞跃过滤无关的特征Yolo 的问题 背景 在计算视觉领域,有几个关键的演变。 1)CNN 卷积的出现,这是一个大的创新; 2)从卷积到 AlexNet ,是更…...
路由器和交换机
路由器和交换机分别位于OSI模型和TCP/IP模型的不同网络层次,具体对比如下: 1. 路由器(Router) 所属层级: OSI模型:网络层(第3层)TCP/IP模型:网络互联层(Int…...
jEasyUI 表单验证
jEasyUI 表单验证 引言 jEasyUI 是一款流行的 jQuery UI 扩展库,它提供了丰富的 UI 组件和交互效果,极大地方便了前端开发工作。在 jEasyUI 中,表单验证是一个非常重要的功能,它可以帮助开发者确保用户输入的数据符合预期的格式和规则。本文将详细介绍 jEasyUI 表单验证的…...
PIKE 助力知识库进阶:多模型协作下的精准信息 “捕手”
PIKE(通常指的是字节跳动提出的一种技术)增强检索知识库是一种结合了先进的信息检索技术和知识库管理的系统。它旨在提高知识检索的准确性、效率和召回率,以更好地满足用户对知识的需求。 特点和工作原理 数据增强 :对知识库中…...
使用Ubuntu18恢复群晖nas硬盘数据外接usb
使用Ubuntu18恢复群晖nas硬盘数据外接usb 1. 接入硬盘2.使用Ubuntu183.查看nas硬盘信息3. 挂载nas3.1 挂载损坏nas硬盘(USB)3.2 挂载当前运行的nas 4. 拷贝数据分批传输 5. 新旧数据对比 Synology NAS 出现故障,DS DiskStation损坏,则可以使用计算机和 U…...
Dify票据识别遇到的分支判断不准确问题
已测试这篇文章中 https://zhuanlan.zhihu.com/p/5465385787 使用多分支条件判断使用不同的大模型识别图片内容 发现了细节问题。在使用时若不注意,分支会出现走向不准的问题。 需要关注部分 下方红框处。1,2后不能跟点。否则会出问。除此之外࿰…...
Flutter学习总结之Android渲染对比
一、Android 界面渲染机制(基于原生 View 体系) 1. 核心渲染流程(源码级解析) 三阶段渲染流程(ViewRootImpl驱动): Measure 阶段(measure()): View调用onMea…...
Media streaming mental map
Media streaming is a huge topic with a bunch of scattered technologies, protocols, and formats. You may feel like hearing fragments without seeing the big picture. Let’s build that mental map together — here’s a high-level overview that connects everyt…...
7B斗671B:扩散模型能否颠覆自回归霸权?
模型对决:从7B到671B的意外之战 参数量与性能的反差 DeepSeek V3以6710亿参数稳坐自回归模型的“巨无霸”地位,而70亿参数的Dream 7B却在多项测试中与其不分伯仲。例如,在需要复杂规划的“倒计时任务”中,Dream 7B的解题成功率比…...
WVP-GB28181摄像头管理平台存在弱口令
免责声明:本号提供的网络安全信息仅供参考,不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我联系,我将尽快处理并删除相关内容。 漏洞描述 攻击者可利用漏洞获取当前系统管…...
实验研究:不同物体与落点材质对弹起高度的影响
本研究通过控制变量法,探讨了不同物体(乒乓球和笔)在不同下落高度和落点材质条件下,其弹起高度的变化。实验结果显示,物体类型、下落高度和落点材质均对弹起高度有显著影响。其中,铁碗作为落点材质时&#…...
开源 PDF.js 文件编辑操作
一、PDF.js PDF.js 是 Mozilla 基金会推出的一个使用 HTML5 构建的 PDF 阅读器,它完全使用 JavaScript 编写。作为 Firefox 浏览器的默认 PDF 查看器,PDF.js 具有强大的兼容性和稳定性。它不仅支持 PDF 文件的查看和渲染,还提供了丰富的交互…...
hydra小记(一):深入理解 Hydra:instantiate() 与 get_class() 的区别
hydra小记(一):深入理解 Hydra:instantiate 与 get_class 的区别 深入理解 Hydra:instantiate() 与 get_class() 的区别1. hydra.utils.get_class()2. hydra.utils.instantiate()3. 总结对比 深入理解 Hydra࿱…...
在 macOS 上安装和配置 Aria2 的详细步骤
在 macOS 上安装和配置 Aria2 的详细步骤: 1.安装 Aria2 方式一:使用 Homebrew Homebrew 是 macOS 上的包管理器,可以方便地安装和管理软件包。 • 打开终端。 • 输入以下命令安装 Aria2: brew install aria2• 检查安装是否…...
Linux开发工具——make/makefile
📝前言: 这篇文章我们来讲讲Linux开发工具——make/makefile: 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀CSDN主页 愚润求学 🌄其他专栏:C学习笔记…...
生信分析服务MR孟德尔随机化单细胞测序转录组数据分析网络药理学
将孟德尔随机化(MR)、单细胞测序、转录组数据分析和网络药理学结合,是当前生物信息学领域的前沿方法,尤其在疾病机制解析、靶点发现和药物研发中展现出巨大潜力。以下从技术逻辑、应用场景和服务流程三个维度展开说明:…...
Sentinel实战(五)、系统保护规则、限流后统一处理及sentinel持久化配置
Spring Cloud Alibaba-Sentinel实战(五)、系统保护规则、限流后统一处理及sentinel持久化配置 一、系统保护规则一)、系统规则支持的模式二)、新增系统规则界面三)、demo测试二、限流后统一处理实操demo三、sentinel持久化配一、系统保护规则 系统保护规则是从应用级别的…...
iPhone XR:一代神机,止步于此
什么样的 iPhone ,才配称为一代神机? 我曾经用过iPhone 4S、iPhone 6S Plus、iPhone 8 Plus,iPhone SE2、iPhone XR、iPhone 13、iPhone 14 Plus、iPhone 15/Pro。 不管硬件再怎么卷,不管囊中是否羞涩,主力机基本没考…...
[C++面试] explicit面试8问 —— 较难,可简单了解即可
Google C规范建议所有单参数构造函数必须加explicit,除非明确需要隐式转换(如std::string从const char*构造)。 1. 隐式转换的实际危害 隐式转换可能导致资源泄漏或逻辑错误(如std::vector<int> v 10;可能被误认为初始化…...
2024-2025 CSS前沿技术全景解析:构建下一代Web界面的核心武器库
前言:CSS的范式革命 当WebAssembly与JavaScript持续争夺开发者注意力时,CSS正在经历一场静默的革命。2024年CSS工作组发布的Level 4/5草案,标志着样式语言正式进入「智能样式」时代。本文将从15个维度深入剖析未来两年最具变革性的CSS新特性…...
flutter row里面怎么统一高度
在 Flutter 中,Row 是一个水平布局的组件,默认情况下,它的子组件的高度是根据每个子组件的内容自动调整的。如果你希望 Row 中的所有子组件具有统一的高度,可以通过以下几种方式实现。 1. 使用 SizedBox 或 Container 设置固定高度…...
pinia-plugin-persist、vuex
pinia-plugin-persist 作用:为 Pinia 状态管理库实现状态持久化,自动将指定的 Pinia store 状态保存到本地存储(如 localStorage 或 sessionStorage),并在应用启动时从本地存储恢复状态。效果:确保应用状态…...
Spring Boot整合MyBatis-Plus实现CRUD操作教程
本文将演示如何在Spring Boot项目中整合MyBatis-Plus框架,快速实现数据库的增删改查操作。相较于原生MyBatis,MyBatis-Plus提供了更简洁的API和自动化功能。 环境准备 JDK 1.8MySQL 5.7Spring Boot 2.7.xMyBatis-Plus 3.5.x 实现步骤 1. 创建项目并添加…...
Vue 3 的响应式原理
Vue 3 的响应式原理可以比喻为“智能监控系统”:当数据变化时,它能自动追踪依赖关系并触发更新。以下是通俗解释和核心机制: 一、核心原理:Proxy 代理 Vue 3 的响应式系统基于 JavaScript 的 Proxy 对象实现(Vue 2 使…...
使用Scrapy官方开发的爬虫部署、运行、管理工具:Scrapyd
一般情况下,爬虫会使用云服务器来运行,这样可以保证爬虫24h不间断运行。但是如何把爬虫放到云服务器上面去呢?有人说用FTP,有人说用Git,有人说用Docker。但是它们都有很多问题。 FTP:使用FTP来上传…...
基于51单片机和8X8点阵屏、独立按键的单人弹球小游戏
目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、8X8点阵屏2、独立按键3、定时器04、定时器1 四、主函数总结 系列文章目录 前言 用的是普中A2开发板,用到板上的独立按键、8X8点阵屏。 【单片机】STC89C52RC 【频率】12T11.0592MHz 效果查看/操作…...
群体智能避障革命:RVO算法在Unity中的深度实践与优化
引言:游戏群体移动的挑战与进化 在《全面战争》中万人战场恢弘列阵,在《刺客信条》闹市里人群自然涌动,这些令人惊叹的场景背后,都离不开一个关键技术——群体动态避障。传统路径规划算法(如A*)虽能解决单…...
Java 实现选择排序:[通俗易懂的排序算法系列之一]
引言 大家好!从今天开始,我计划写一个关于常见排序算法的系列文章,旨在用通俗易懂的方式,结合 Java 代码实现,帮助大家理解和掌握这些基础但非常重要的数据结构与算法知识。 排序是计算机科学中最基本的操作之一&…...
动画过渡设置
使用Animator的Trigger参数 步骤 1:打开 Animator 窗口 确保你的 Sprite 对象已添加 Animator 组件。 在 Unity 编辑器顶部菜单栏,选择 Window > Animation > Animator,打开 Animator 窗口。 步骤 2:创建 Trigger 参数 在…...
【项目管理-高项】学习方法 整体概览
相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 📝 软考高项,全称 信息系统项目管理师 ,是软考高级资格项目之一。 本考试考三门科目:综合知识(上午)、案例分析(下午…...