news 2026/10/24 7:29:20

React Native for OpenHarmony 实战:三方库 react-native-loading-spinner-overlay 的鸿蒙化适配指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React Native for OpenHarmony 实战:三方库 react-native-loading-spinner-overlay 的鸿蒙化适配指南

本文记录把react-native-loading-spinner-overlay适配到 HarmonyOS 的完整过程。

这个库很小(两个源文件、约 3 KB),也很纯粹:一个全屏的加载遮罩,零运行时依赖、没有prepare脚本、连编译产物都与上游逐字符一致。接入本身毫无难度。

但它带来的验证问题比接入问题有意思得多:

  1. 它的所有渲染都在 RN 的Modal里(transparent+statusBarTranslucent)⇒ 要测的是RNOH 的 Modal + 半透明遮罩;
  2. 遮罩一起,它就把页面上所有触摸都吞掉了—— 这让我原本设计的"遮罩显示期间点按钮触发重渲染"的实验根本无法执行;
  3. 它是半受控的:cancelable被返回键关闭后,组件内部认为已关闭、父组件的visible却还是true,而库没有任何回调告知父组件。

第 3 条是这轮最有价值的发现:它是一个真实的行为缺陷,而且只靠读源码 + 一个四步实测就能坐实。


一、先说结论

项结果
上游最新版3.0.1(MIT);gitHead=84896fa0284b705f136622dcd0d7f17184f747bb
库类型纯 JS 函数组件,渲染在 RN 的Modal内
是否需要原生适配不需要(无harmony/、无NativeModules)
运行时依赖零(dependencies字段不存在)
prepare/prepack都没有⇒ 安装路径干净
与 npm 上游的差异11 / 12 个文件去掉 CR 后逐字符一致(含src/**与lib/**编译产物);唯一差异是package.json
编译assembleHap3 分 52 秒;HAP82,083,102 字节(+32,770)
设备侧断言12 / 14(A 10/10、B 1/1、C 1/1、D 0/2 未验证,原因见第八节)
★ 外部实测(全部命中)遮罩文字 Y =1281(几何预言逐像素吻合);rgba(0,0,0,0.25)实测亮度×0.75;rgba(255,0,0,1)全屏(254,0,0)(含状态栏区域);遮罩吞掉全部页面触摸(有对照组)
★ 一个真实的行为缺陷半受控:cancelable关闭后组件(false) 与父组件 prop(true)长期不一致,且库不接受onRequestClose、无任何回调
★ 未验证的一条不传spinnerKey时"每次渲染都重挂载 Modal" ——代码级事实成立,运行时挂载计数本轮没取到(原因正是第 5 节那条)

一句话结论:库本身能用、几何与像素都对;但要记住它会吞掉页面所有交互,以及它的关闭是"半受控"的。


二、判定过程:三步走完,而且是这一系列里最干净的一个

步做法结果
①package.json里有没有harmony.autolinking没有
②仓库里有没有harmony/没有
③代码里有没有NativeModules/requireNativeComponent全无

dependencies字段直接不存在 ⇒零运行时依赖。

再补两项这个库特有的确认(这两项在前面的库里都出过事):

检查结果为什么值得单独查
scripts里有没有prepare/prepack都没有(只有build/lint/test)有的库在prepare里会删掉随包发布的编译产物,导致安装失败、包静默损坏
入口在哪main: lib/index.js,lib/已提交这类"入口是编译产物"的包要确认lib/与src/行为一致(否则你读的源码不是真正跑的东西)

关于第二项的核实方式:这个包的tsconfig.json写的是"target": "esnext"且没有写module⇒ 编译产物是ESM(import/export default)。这意味着在 PC 上用 Noderequire()它是不行的,所以我没有做 PC 侧探针,而是直接读lib/index.js这份运行时真正执行的代码,并逐行核对它与src/index.tsx行为一致 ⇒排除"陈旧编译产物"这个风险。


三、交付包质量

3.1 与 npm 上游逐文件比对(先去 CR)

类别结果
一致11 个文件(src/**、lib/**全部编译产物、README.md、LICENSE、tsconfig.json等)
不同1 个:package.json
交付包缺少0
交付包多出6 个:.gitignore、两个README.OpenHarmony*、代码检查报告、spec.json、契约测试

实现与产物双重零改动,而且没有prepare⇒ 这是本系列里安装路径最干净的一个。

3.2 一个"看着像错、查证后没错"的地方

spec.json里的上游地址写的是git+ssh://git@github.com/...(SSH 形式)。第一眼像是不该这么写 —— 但查 npm 的repository字段,上游自己就是这么写的⇒不是缺陷。

教训:"名字/格式不一致"要先查数据源再定性。

3.3 问题

问题说明
spec.json缺upstreamCommit而 npm明确有gitHead(84896fa0…)⇒属应修项
validation是裸字符串"pass"没有可复核的测试项清单
契约测试是包级 smoke test只检查包名 / 版本 / 主入口存在 / 中文 README 存在,一次组件都没渲染过
两个交付 README都没写三件事① 组件是半受控的;②遮罩会吞掉页面所有触摸;③ 不传spinnerKey会重挂载

四、几何与像素:三条预言全部命中

4.1 遮罩文字的位置(逐像素吻合)

源码里textContent的样式是:

textContent:{fontSize:20,fontWeight:'bold',height:50,top:80}

而它的容器是全屏绝对定位 +justifyContent: 'center'。

先算一遍(设备 density = 3,屏高 2232px):

文字上边 = 屏幕中心 − 文字半高 + top = 2232/2 − (50vp/2 × 3) + (80vp × 3) = 1116 − 75 + 240 = 1281

实测:Text [433,1281,887,1431] "SPIN-TEXT-DIM"⇒Y1 = 1281✓ 高度 150px 也正好是50vp × 3✓

⇒这个库的布局在 RNOH 上与设计完全一致。

4.2 半透明遮罩的"变暗比例"(数值精确)

overlayColor默认是'rgba(0, 0, 0, 0.25)',作用在全屏容器上。在同一个像素位置比较"无遮罩 / 有遮罩":

位置(下面的页面元素)无遮罩有遮罩比值
(100,1700) 蓝色按钮#1f6feb(31,111,234)(23,84,177)0.742 / 0.757 / 0.756
(660,1700) 页面背景#0f1115(16,17,21)(12,13,17)0.750 / 0.765 / 0.810

⇒实测比值 ≈ 0.75 = 1 − 0.25✓ 遮罩确实是"整体压暗 25%",而不是别的混合方式。

4.3 纯红遮罩顺带证实了statusBarTranslucent

把overlayColor换成'rgba(255, 0, 0, 1)':

采样点实测
(100,300) / (660,900) / (1200,2100)(254,0,0)
(60,60) —— 状态栏区域(254,0,0)

遮罩全屏铺满,连状态栏区域都被盖住—— 这正好证实了源码里的:

<Modal … statusBarTranslucent={true}>

是真的生效的。



五、遮罩会吞掉页面所有触摸(带对照组)

这一条我先踩坑、后做对照才定性。

现象:遮罩显示后,用工具按坐标点页面上的按钮,工具报成功,但设备日志里没有任何对应的记录,遮罩也没关。

对照实验:

情形结果是否产生日志
无遮罩时点「显示 纯红遮罩」红遮罩出现✅ 有
遮罩在时点「隐藏全部遮罩」无任何日志,遮罩仍在❌ 无

⇒Modal窗口把页面所有触摸都吞掉了。

两个结论:

  1. 遮罩显示期间,用户点不到下面任何东西(这是 loading 遮罩的意图,但写代码时要意识到:"加载中禁止操作"是自动的,不需要额外加pointerEvents);
  2. ⚠️方法论:坐标点击工具报成功只代表"坐标被点到了",不代表按钮被按下。有东西盖着时它照样报成功。以后凡是"点了没反应",都要先做一次"无遮挡时点同一个按钮"的对照。

六、cancelable的真实触发源是返回键,不是点遮罩

源码里:

constclose=()=>{setSpinnerVisibility(false);};const_handleOnRequestClose=()=>{if(cancelable){close();}};<Modal onRequestClose={()=>{_handleOnRequestClose();}}…>

两个要点:

  1. 组件根本不接受onRequestCloseprop—— 它内部只有一个私有的_handleOnRequestClose,从外面传什么都不起作用;
  2. RN 的Modal.onRequestClose由返回键 / 返回手势触发,不是点遮罩触发⇒cancelable必须用返回键来验。

实测:

实例按返回键后结论
cancelable未设(= false)遮罩仍在✓ 与if (cancelable)一致;且返回键没有把应用退出(被 Modal 消费了)
cancelable= true遮罩关闭✓cancelable经Modal.onRequestClose生效

⚠️别把cancelable理解成"点遮罩可以关闭"。它的实际含义是"允许返回键关闭"。


七、半受控语义:本轮最有价值的发现

7.1 源码

const[spinnerVisible,setSpinnerVisibility]=React.useState(visible);// ① 内部自己存一份React.useEffect(()=>{setSpinnerVisibility(visible);},[visible]);// ② 只在 visible 变化时同步constclose=()=>{setSpinnerVisibility(false);};// ③ 关闭只改内部状态

⇒cancelable被返回键关闭时:只改了组件内部状态,没有通知父组件;而useEffect的依赖[visible]没变⇒不会重新同步。

7.2 四步实测(全部命中)

步骤观测结论
① 点「显示 cancelable」遮罩出现(文字 Y = 1281)打开正常
② 按返回键遮罩关闭;日志里没有父组件的新动作父组件 prop 仍是true
③ 让父组件用同样的visible={true}重渲染 3 次遮罩没有重新出现✅边界坐实:组件(false) 与父组件(true) 长期不一致
④ 把visible走一次 false→true遮罩重新出现✅ 与[visible]依赖一致

7.3 为什么这是个缺陷

  • 库不提供任何回调告知父组件"我被关掉了"(它连onRequestCloseprop 都不接受);
  • ⇒ 父组件无从得知。如果它一直保持visible={true},就会长期处于"父组件以为在显示、实际已经关了"的不一致状态;
  • 而且遮罩不会自己回来,除非父组件主动把visible走一次 false→true。

规避做法:

// 父组件自己掌握状态;要用 cancelable 就自己监听返回键 const [visible, setVisible] = useState(false); useEffect(() => { const sub = BackHandler.addEventListener('hardwareBackPress', () => { if (visible) { setVisible(false); return true; } // 自己关,自己知道 return false; }); return () => sub.remove(); }, [visible]); <Spinner visible={visible} cancelable={false} textContent="加载中" />;


八、一条"代码级成立、运行时未验证"的行为

8.1 代码级事实

<View style={[styles.container, …]} key={spinnerKey || `spinner_${Date.now()}`}>

Date.now()每次渲染都不同⇒ 不传spinnerKey时这个key每次渲染都变⇒ 按 React 语义,该子树会被卸载再重新挂载。这解释了spinnerKey这个 prop 为什么存在:想避免重挂载就得给一个稳定的 key。

8.2 为什么本轮没测到

我原本的设计是:传一个挂载时会打日志的customIndicator,然后在遮罩显示期间点"重渲染"按钮,数挂载次数。

但这个设计被第 5 节推翻了:遮罩一起就吞掉所有触摸 ⇒我没法在遮罩显示期间点到页面按钮⇒ 父组件不会重渲染 ⇒挂载计数拿不到。

所以这一轮的 D 组两条断言如实失败:

✗ [D] 不传 spinnerKey 的实例挂载次数 > 1(每次渲染都重挂载)|期望 true|实际 false ✗ [D] 固定 spinnerKey 的实例挂载次数更少|期望 true|实际 false · NO-KEY 挂载次数 = 0 FIXED-KEY 挂载次数 = 0

补测的正确做法:在页面里加一个自驱动计时器(遮罩显示期间自动触发父组件重渲染),这样就不依赖外部点击 —— 但这需要再改一次页面并重编。本轮为控制时长没有做。

⇒这一条只能记成"代码级事实成立、运行时未验证",不能写成"已实测"。


九、已知限制与本次验证边界

9.1 用这个库要知道的四件事

事项说明
安装无prepare,普通npm install即可(本系列仍统一加--ignore-scripts)
遮罩会吞掉页面所有触摸显示期间下面的按钮全点不到;也点不到遮罩来关闭
cancelable= 允许返回键关闭不是"点遮罩关闭";而且不会通知父组件
半受控组件自己关掉后,父组件的visible=true不会让它重开;要 false→true
spinnerKey不给的话每次渲染都会重挂载 Modal 子树(代码级;运行时未验)
不接受onRequestCloseprop想在关闭时做事情,只能自己在父组件监听返回键

9.2 本次验证的边界

  1. 只在一台模拟器上验证(Pura X View,density 3,1320×2232),没有真机。
  2. 重挂载行为(D 组)未在运行时验证(原因见第八节)。
  3. animation('none'/'slide'/'fade')完全未测—— 本轮只用默认的'none';Modal 动画在 RNOH 上的表现未知。
  4. size='small'与数值型size未测(只用了默认'large');源码注释说不支持'normal',但没实测传'normal'会怎样。
  5. color(指示器颜色)未做像素核对(本轮只核对了遮罩色)。
  6. indicatorStyle/textStyle自定义未测。
  7. customIndicator/children自定义内容只用于挂载计数,没有渲染可测内容的布局/交互。
  8. 多个 Spinner 同时visible的叠加/层级未测(本轮六个实例每次只显示一个)。
  9. children与customIndicator同时存在时的优先级未做组合实测(源码是children || _renderDefaultContent()、customIndicator || ActivityIndicator)。
  10. visible从 true→false 的关闭时序/动画未测。
  11. 点遮罩本身是否有其它副作用未细测(已确认"不会关闭")。
  12. 没有跨平台对照(未在 iOS/Android 上跑同一套用例)。

未改动库代码。


十、常见问题

Q1:怎么接入?

npminstall"git+https://atomgit.com/oh-react-native/react-native-loading-spinner-overlay.git#3.0.1-ohos-1.0.0"--ignore-scripts
// metro.config.js —— file: / 软链装法需要把真实目录加进 watchFolderswatchFolders:[path.resolve(__dirname,'../react-native-loading-spinner-overlay')],
import Spinner from 'react-native-loading-spinner-overlay'; <Spinner visible={loading} textContent="加载中…" />;

不需要HAR、权限、ohpm、link-harmony。

Q2:遮罩显示时,我还能操作页面上的按钮吗?

不能。它渲染在一个全屏的Modal窗口里,会吞掉页面所有触摸(实测:有遮罩时点页面按钮,设备日志里没有任何反应)。

这通常正是你要的效果(加载中禁止操作),但要知道:这个"禁止操作"是自动发生的,你不需要另外加pointerEvents;反过来说,也别指望"点一下遮罩就能关掉它"。

Q3:cancelable是不是"点遮罩可以关闭"?

不是。cancelable的真实含义是"允许返回键关闭":

const_handleOnRequestClose=()=>{if(cancelable){close();}};<Modal onRequestClose={()=>_handleOnRequestClose()}…>

Modal.onRequestClose由返回键/返回手势触发,点遮罩不会触发。实测:cancelable=false时按返回键不关;cancelable=true时按返回键关闭。

Q4:我想在遮罩被关闭时做点事情,可以传onRequestClose吗?

不行,这个组件根本不接受这个 prop —— 它内部只有一个私有的_handleOnRequestClose。

Q5:我传了visible={true},用户按返回键关掉之后,为什么它不再出现了?

因为它内部自己存了一份visible状态,cancelable关闭时只改了内部状态:

const[spinnerVisible,setSpinnerVisibility]=useState(visible);useEffect(()=>setSpinnerVisibility(visible),[visible]);

useEffect的依赖是[visible],而父组件传的值一直是true(没变)⇒不会重新同步⇒ 遮罩保持关闭。实测已坐实:父组件用同样的visible={true}重渲染 3 次,遮罩也不会回来;只有把visible走一次false→true才会重新出现。

Q6:那正确的用法是什么?

父组件自己掌握状态,并且自己监听返回键(不要依赖库的内部行为):

const [visible, setVisible] = useState(false); useEffect(() => { const sub = BackHandler.addEventListener('hardwareBackPress', () => { if (visible) { setVisible(false); return true; } return false; }); return () => sub.remove(); }, [visible]); <Spinner visible={visible} cancelable={false} textContent="加载中…" />;

Q7:spinnerKey是干什么的?

源码里那一行是:

key={spinnerKey || `spinner_${Date.now()}`}

不传spinnerKey时,key每次渲染都不一样⇒ 按 React 语义,这个子树每次渲染都会被卸载再重新挂载(造成不必要的开销/闪烁)。给它一个固定字符串就能避免。

(⚠️ 这条是代码级事实;本轮的运行时挂载计数没能取到,原因见第八节,所以我没有把它写成"已实测"。)

Q8:遮罩的默认样式能改吗?

可以。overlayColor改全屏底色、color改指示器颜色、size改指示器大小、textContent/textStyle改文字、indicatorStyle改指示器与文字容器的样式。

实测:overlayColor默认'rgba(0, 0, 0, 0.25)'会把屏幕整体压暗到 75% 亮度;传'rgba(255, 0, 0, 1)'则整屏变纯红,连状态栏区域也盖住(因为statusBarTranslucent为 true)。

Q9:size能传'normal'吗?

源码注释明确写着size不支持'normal',类型是'small' | 'large' | number。(本轮只实测了默认的'large',传'normal'的实际表现未验证。)

Q10:遮罩打开后我卡住了,怎么把它弄掉?

  • cancelable=true的实例:按返回键;
  • cancelable=false的实例:返回键关不掉(这是设计行为),页面按钮又被吞了 ⇒ 只能重启应用(aa force-stop+ 重新aa start)。

这是设计测试页时就要想好的事:有覆盖层的组件,每种状态都要有"退出来"的路,否则后续步骤会被卡死。


小结

react-native-loading-spinner-overlay是一个很小、很干净的纯 JS 库:零运行时依赖、没有prepare、11/12 个文件(含全部编译产物)与上游逐字符一致。几何与像素实测全部命中:遮罩文字位置误差0 像素、rgba(0,0,0,0.25)的压暗比例实测×0.75、纯红遮罩全屏(254,0,0)且覆盖状态栏。

值得记下来的是这几条:

  1. "点了没反应"要先做无遮挡的对照。遮罩一起,坐标点击工具照样报成功,但点击被 Modal 窗口吞掉、什么都没发生。⇒工具报成功 ≠ 按钮被按下;先分离"没点到"和"功能没生效"。

  2. 读源码要读运行时真正执行的那一份。这个包main指向ESM 的编译产物(target: esnext且没写module),Node 端require不了⇒ PC 探针这条路走不通,只能直接读lib/并核对它与src/一致。这一步顺带排除了"陈旧编译产物"的风险。

  3. cancelable这类 prop 要先确定"触发源"。我第一版页面给组件传了onRequestClose——它根本不接受;而Modal.onRequestClose是返回键触发的,不是点遮罩。⇒写交互断言前先确认"这个交互由什么事件触发",否则会写出一个永远不会触发的断言。

  4. "半受控"是这类组件的隐藏陷阱。组件内部useState(props.x)+useEffect([x])同步,同时又允许自己改这份状态 ⇒它一旦自己改了,父组件就被蒙在鼓里。⇒凡是组件内有useState(props.x),都要专门测"组件自己改了这份状态之后,父组件的 prop 还有效吗"。这里的答案是:无效,而且库没有任何回调能通知你。

  5. 有覆盖层的组件,测试设计要预留"退出路径"。遮罩吞触摸 ⇒ 页面按钮全失效 ⇒ 只能靠返回键或重启;而cancelable=false的实例返回键也关不掉。⇒设计测试页时就要想好每种状态怎么退出来。

  6. "代码级成立"和"已实测"是两件事。key每次渲染都变 ⇒ React 必然重挂载,这是确定的语义;但我这一轮没能在运行时把挂载次数测出来(被遮罩吞触摸挡住了)。⇒如实写成"代码级事实成立、运行时未验证",而不是含糊地当成已验证。


本篇用到的库

项内容
三方库react-native-loading-spinner-overlay(上游3.0.1的鸿蒙适配版)
适配仓库https://atomgit.com/oh-react-native/react-native-loading-spinner-overlay
适配 TAG3.0.1-ohos-1.0.0
需要 HAR / 权限 / ohpm都不需要(纯 JS,零运行时依赖)
库类型纯 JS 函数组件:全屏加载遮罩,渲染在 RNModal内
运行时依赖零(dependencies字段不存在)
prepare/prepack都没有⇒ 安装路径干净
许可证MIT
上游仓库https://github.com/joinspontaneous/react-native-loading-spinner-overlay
上游基线npmgitHead=84896fa0284b705f136622dcd0d7f17184f747bb
宿主工程RNOH084Demo(测试页rnAppKey = LoadingSpinnerTestApp)
# 从适配仓库安装npminstall"git+https://atomgit.com/oh-react-native/react-native-loading-spinner-overlay.git#3.0.1-ohos-1.0.0"--ignore-scripts# 或本地 file: 安装(装成软链,需要配 watchFolders)npminstall../react-native-loading-spinner-overlay --ignore-scripts
// metro.config.js —— file: / 软链装法需要把真实目录加进 watchFolderswatchFolders:[path.resolve(__dirname,'../react-native-loading-spinner-overlay')],
// 用法:父组件自己掌握状态 + 自己监听返回键(不要依赖库的内部行为) import Spinner from 'react-native-loading-spinner-overlay'; import {BackHandler} from 'react-native'; const [loading, setLoading] = useState(false); useEffect(() => { const sub = BackHandler.addEventListener('hardwareBackPress', () => { if (loading) { setLoading(false); return true; } return false; }); return () => sub.remove(); }, [loading]); <Spinner visible={loading} textContent="加载中…" overlayColor="rgba(0, 0, 0, 0.25)" // 实测:屏幕亮度 ×0.75 color="#ffffff" size="large" // 不支持 'normal';也可传数值 spinnerKey="main-spinner" // 建议给固定值,避免每次渲染重挂载 cancelable={false} // true 时允许返回键关闭(且不会通知父组件) />;
# 换页启动测试页(force-stop 不能省,换页参数只在冷启动生效)hdc shell aa force-stop com.rnoh084.demo hdc shell aa start-bcom.rnoh084.demo-aEntryAbility--psrnAppKey LoadingSpinnerTestApp

环境搭建

本手册的验证环境是React Native for OpenHarmony(RNOH)。从零准备开发环境(DevEco Studio、HarmonyOS SDK API 26、Node.js、ohpm、hvigorw、模拟器与hdc调试)请按 CPF-RN 开发者指南的「环境初始化」操作:

  • CPF-RN 开发者指南 · 02-搭建准备 · 环境初始化:https://atomgit.com/CPF-RN/docs/blob/main/开发者指南/02-搭建准备/环境初始化.md

环境就绪后,本次验证使用的具体版本组合见文末「验证环境」一节。


验证环境

项版本
React Native0.84.1
React19.2.3
RNOH(npm / ohpm)@react-native-oh/react-native-harmony/@rnoh/react-native-openharmony0.84.3
Node.js / npmv24.14.0/11.9.0
DevEco Studio26.0.0.621
HarmonyOS SDKAPI 26(26.0.0.32)
设备HarmonyOS 7.0.0(26.0.0) Beta2 模拟器Pura X View(ohos-x64),1320×2232,density 3
宿主 HAP 产物entry-default-signed.hap(82,083,102 字节)
本次增量构建assembleHap3 分 52 秒,HAP +32,770 字节;打包资源 14(无新增,符合预期)
验证规模设备侧12 / 14(A 10/10、B 1/1、C 1/1、D 0/2 未验证);外部含几何逐像素核对 1 次、像素取样 7 点、吞触摸对照 2 组、返回键 2 例、半受控四步、上游 12 个文件逐字符比对

欢迎加入 CPF-RN 鸿蒙社区:https://atomgit.com/CPF-RN

React Native for OpenHarmony 组织:https://atomgit.com/oh-react-native

RN 三方库鸿蒙适配清单:https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 7:29:05

双 11 赛博朋克霓虹流光背景:基于 Signed Distance Fields 符号距离场的 GPU 动态排版光晕

在双 11 狂欢夜与主会场视觉搭建中&#xff0c;视觉设计师往往追求强烈的赛博朋克霓虹氛围&#xff1a;极具未来感的几何晶格、沿着版面边缘川流不息的能量光导流光、以及与品牌主标题深度融合的弥散辉光。在以往的工程实践中&#xff0c;前端团队大多依赖 UI 团队切出的大尺寸…

作者头像 李华
网站建设 2026/10/24 7:28:10

从克隆到第一次录制:LiveAutoRecord 直播自动录制实用笔记

从克隆到第一次录制&#xff1a;LiveAutoRecord 直播自动录制实用笔记 【免费下载链接】LiveAutoRecord 基于 Electron 的多平台直播自动录制软件 项目地址: https://gitcode.com/GitHub_Trending/li/LiveAutoRecord 周六决赛开打前&#xff0c;你不想熬夜盯着整场直播&…

作者头像 李华
网站建设 2026/10/24 7:27:26

开源桌面机器人 Reachy Mini:六自由度平台控制好不好上手

开源桌面机器人 Reachy Mini&#xff1a;六自由度平台控制好不好上手 【免费下载链接】reachy_mini Reachy Minis SDK 项目地址: https://gitcode.com/GitHub_Trending/re/reachy_mini Reachy Mini 是一款开源桌面机器人&#xff0c;头部是六自由度斯图尔特平台&#xf…

作者头像 李华
网站建设 2026/10/24 7:25:34

Mybatis调用存储过程返回sys_refcursor,对象集合映射配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/24 7:20:46

Redisson延迟队列实现原理与电商应用实践

1. Redisson延迟队列实现方案解析 延迟队列作为分布式系统中常见的解耦利器&#xff0c;在订单超时取消、定时任务触发等场景中扮演着重要角色。Redisson这个Java界的Redis客户端之王&#xff0c;提供了开箱即用的延迟队列实现方案&#xff0c;相比自己造轮子&#xff0c;它解…

作者头像 李华