rsuite Animation 组件实战指南:Fade、Collapse、Bounce、Slide 与自定义 Transition 动画
前端UI组件【免费下载链接】rsuite A suite of React components .项目地址https://gitcode.com/gh_mirrors/rs/rsuite点击查看免费下载rsuite 的Animation是一组开箱即用的动画组件集合用于为元素的显示与隐藏赋予平滑的过渡效果。本文以 Animation 官方文档 为主线结合 组件实现源码 与 单元测试系统讲解Animation.Fade、Animation.Collapse、Animation.Bounce、Animation.Slide以及可完全自定义的Animation.Transition的用法、Props 与底层状态机原理帮助你快速在项目里实现高质量的交互动画。一、Animation 组件总览与导入Animation组件是一组动画组件的集合你不需要安装任何额外的动画库通过配置相关属性即可获得动画效果。它由 5 个子组件组成全部导出自 src/Animation/index.tsx子组件说明Animation.Fade淡入淡出动画Animation.Collapse折叠高度/宽度收放动画Animation.Bounce弹跳动画Animation.Slide滑动动画Animation.Transition自定义动画可接入任意 CSS animation从源码可以看出Animation是一个聚合对象五个子组件均通过React.forwardRef实现并共享同一个Transition内核export const Animation: AnimationAPI { Transition, Collapse, Fade, Bounce, Slide };使用方式也非常灵活既可以整体引入也可以单独按需引入import { Animation } from rsuite; // 或按需引入单个组件 import Fade from rsuite/Animation/Fade;所有动画子组件的共同特征是children 既可以是一个普通 React 元素也可以是一个渲染函数(props, ref) ReactNode后者会将className与ref透传给目标节点便于精确控制动画作用在哪个 DOM 元素上。二、核心机制Transition 状态机在深入各个组件之前先理解所有动画的底层引擎Transition。它定义了一个五态状态机见 src/Animation/Transition.tsxexport enum STATUS { UNMOUNTED 0, // 组件未挂载配合 unmountOnExit 使用 EXITED 1, // 退出完成已隐藏 ENTERING 2, // 正在进入 ENTERED 3, // 进入完成已显示 EXITING 4 // 正在退出 }当in属性变化时组件会在这些状态之间迁移并在每个阶段切换对应的 CSS class状态生效的 className触发的回调exited退出完成exitedClassNameonExitedexiting退出中exitingClassNameonExit/onExitingentering进入中enteringClassNameonEnter/onEnteringentered进入完成enteredClassNameonEntered源码中的performEnter/performExit是状态迁移的核心Transition.tsx它们先回调onEnter/onExit将状态置为ENTERING/EXITING后回调onEntering/onExiting再通过onTransitionEnd监听节点的transitionend/animationend事件或超时兜底完成状态收尾。值得注意的是监听事件由animation属性决定Transition默认监听transitionend而Bounce、Slide这类基于keyframes的动画会显式传入animation通过 utils.ts 中的getAnimationEnd()自动适配webkitAnimationEnd与标准animationend默认timeout兜底机制保证即使 CSS 动画事件异常状态机也能按超时时间完成迁移Transition默认 1000msunmountOnExit为 true 时动画结束后组件会从 DOM 中彻底移除STATUS.UNMOUNTED时render返回null这在列表、弹层等场景可减少无谓的 DOM 节点。下面按组件逐一展开先看官方示例代码完整示例位于 docs/pages/components/animation/fragments再对照 Props 表格与源码原理。三、Animation.Fade淡入淡出Animation.Fade是最常用的基础动画适用于弹窗遮罩、提示层、内容区切换等任何需要淡入淡出的场景。3.1 官方示例import { Animation, Button, Card } from rsuite; const AnimatedPanel React.forwardRef((props, ref) ( Card {...props} ref{ref} shaded bordered{false} w{240} h{120} cwhite bglinear-gradient(45deg, #4CAF50, #2196F3) div Card.HeaderFade Animation/Card.Header Card.BodyThis panel demonstrates a smooth fade transition effect./Card.Body /div /Card )); const App () { const [show, setShow] React.useState(true); const onChange () setShow(!show); return ( div Button appearanceprimary onClick{onChange} Toggle Fade /Button hr / div Animation.Fade in{show} {(props, ref) AnimatedPanel {...props} ref{ref} /} /Animation.Fade /div /div ); }; ReactDOM.render(App /, document.getElementById(root));要点通过in布尔值控制动画开关children 使用渲染函数把props和ref转发给内部节点。完整示例见 fade.md。3.2Animation.FadePropsPropertyType(Default)DescriptionenteredClassNamestring组件进入动画完成之后添加的 classNameenteringClassNamestring组件开始进入动画时添加的 classNameexitedClassNamestring组件退出动画完成之后添加的 classNameexitingClassNamestring组件开始退出动画时添加的 classNameinboolean为 true 时显示组件并播放进入动画onEnter(node?: null, Element, Text) void进入动画开始前触发的回调onEntered(node?: null, Element, Text) void进入动画完成后触发的回调onEntering(node?: null, Element, Text) void进入动画开始时触发的回调onExit(node?: null, Element, Text) void退出动画即将开始时触发的回调onExited(node?: null, Element, Text) void退出动画完成后触发的回调onExiting(node?: null, Element, Text) void退出动画开始时触发的回调timeoutnumber(300)动画过渡时长transitionAppearboolean首次渲染即显示时是否也播放进入动画unmountOnExitboolean退出后是否将组件从 DOM 中卸载3.3 源码原理查看 Fade.tsx 可以看到Fade 本质上是Transition的预配置封装Transition {...propsWithDefaults} ref{ref} timeout{timeout} // 默认 300 className{merge(className, prefix(fade))} // rs-anim-fade enteredClassName{prefix(in)} // rs-anim-in enteringClassName{prefix(in)} // rs-anim-in /对应的样式在 styles/_fade.scss.rs-anim-fade { opacity: 0; transition: opacity var(--rs-anim-fade-duration) linear; pointer-events: none; .rs-anim-in { opacity: 1; pointer-events: auto; } }从源码结构可以推断隐藏状态下不仅opacity: 0还设置了pointer-events: none避免不可见的层拦截点击进入时恢复pointer-events: auto。动画时长由 CSS 变量--rs-anim-fade-duration默认0.15s见 styles/_variables.scss控制而timeout属性则用于 JS 侧的状态机兜底计时。rsuite 内部组件也大量复用了 Fade例如 Modal 遮罩 使用Fade transitionAppear in{open} timeout{backdropTransitionTimeout}实现弹窗背景层的淡入淡出。四、Animation.Collapse折叠展开Animation.Collapse适用于手风琴面板、抽屉菜单、表单分组等需要按高度/宽度收起展开的场景动画基于元素的实际尺寸测量实现。4.1 官方示例示例见 collapse.md同时演示了纵向折叠默认height与横向折叠dimensionwidth两种模式import { Animation, Button, Card } from rsuite; const AnimatedPanel React.forwardRef((props, ref) ( Card {...props} ref{ref} shaded bordered{false} w{240} h{120} cwhite bglinear-gradient(45deg, #4CAF50, #2196F3) div Card.HeaderCollapse Animation/Card.Header Card.Body w{240}Demonstrates vertical and horizontal collapse transitions./Card.Body /div /Card )); const App () { const [show, setShow] React.useState(true); const onChange () setShow(!show); return ( div Button appearanceprimary onClick{onChange} Toggle Collapse /Button hr / HStack spacing{16} alignItemsflex-start VStack w{240} TextVertical Collapse/Text Animation.Collapse in{show} {(props, ref) AnimatedPanel {...props} ref{ref} /} /Animation.Collapse /VStack VStack w{240} TextHorizontal Collapse/Text Animation.Collapse in{show} dimensionwidth {(props, ref) AnimatedPanel {...props} ref{ref} /} /Animation.Collapse /VStack /HStack /div ); };4.2Animation.CollapsePropsPropertyType(Default)Descriptiondimensionheight | width | () (height | width)设置折叠尺寸类型enteredClassNamestring(collapse in)组件进入动画完成之后添加的 classNameenteringClassNamestring(collapsing)组件开始进入动画时添加的 classNameexitedClassNamestring(collapse)组件退出动画完成之后添加的 classNameexitingClassNamestring(collapsing)组件开始退出动画时添加的 classNamegetDimensionValue() number自定义折叠的尺寸数值inboolean为 true 时显示组件并播放进入动画onEnter(node?: null, Element, Text) void进入动画开始前触发的回调onEntered(node?: null, Element, Text) void进入动画完成后触发的回调onEntering(node?: null, Element, Text) void进入动画开始时触发的回调onExit(node?: null, Element, Text) void退出动画即将开始时触发的回调onExited(node?: null, Element, Text) void退出动画完成后触发的回调onExiting(node?: null, Element, Text) void退出动画开始时触发的回调rolestringHTML role 属性timeoutnumber(300)动画过渡时长transitionAppearboolean首次渲染即显示时是否也播放进入动画unmountOnExitboolean退出后是否将组件从 DOM 中卸载4.3 源码原理基于真实尺寸的收放Collapse的关键实现Collapse.tsx是在 Transition 的各个阶段回调中动态读写节点的内联尺寸样式进入阶段handleEnter先把height/width设为0handleEntering读取节点的scrollHeight/scrollWidth作为目标值handleEntered恢复为auto退出阶段handleExit先通过getDimensionValue默认实现为offsetHeight/offsetWidth margin之和取得当前尺寸写入内联样式再通过triggerBrowserReflow强制浏览器回流最后handleExiting将尺寸改为0触发过渡getDimensionValue支持自定义返回数值测试用例 Collapse.spec.tsx 中就用getDimensionValue{() 50}验证了退出时高度被设置为50px、进入折叠后变为0px的行为。dimension既支持字符串也支持返回字符串的函数测试用例同时覆盖了dimension{() DIMENSION.WIDTH}的形式当为width时 className 会追加rs-anim-collapse-horizontal。对应样式见 styles/_collapse.scss其中.rs-anim-collapsing设置了height: 0; overflow: hidden以及基于--rs-anim-collapse-duration默认0.35s的过渡还兼容tr、tbody等表格行的折叠。五、Animation.Bounce弹跳动画Animation.Bounce提供带弹性曲线overshoot的弹跳效果适合消息提醒、徽标强调、卡片入场等需要吸引注意力的场景。5.1 官方示例import { Animation, Button, Card } from rsuite; const AnimatedPanel React.forwardRef((props, ref) ( Card {...props} ref{ref} shaded bordered{false} w{240} h{120} cwhite bglinear-gradient(45deg, #4CAF50, #2196F3) div Card.HeaderBounce Animation/Card.Header Card.BodyThis is a beautiful animated panel that demonstrates the bounce effect./Card.Body /div /Card )); const App () { const [show, setShow] React.useState(true); const onChange () setShow(!show); return ( div Button appearanceprimary onClick{onChange} Toggle Bounce /Button hr / div Animation.Bounce in{show} {(props, ref) AnimatedPanel {...props} ref{ref} /} /Animation.Bounce /div /div ); };完整示例见 bounce.md。5.2Animation.BouncePropsPropertyType(Default)DescriptionenteredClassNamestring组件进入动画完成之后添加的 classNameenteringClassNamestring组件开始进入动画时添加的 classNameexitedClassNamestring组件退出动画完成之后添加的 classNameexitingClassNamestring组件开始退出动画时添加的 classNameinboolean为 true 时显示组件并播放进入动画onEnter(node?: null, Element, Text) void进入动画开始前触发的回调onEntered(node?: null, Element, Text) void进入动画完成后触发的回调onEntering(node?: null, Element, Text) void进入动画开始时触发的回调onExit(node?: null, Element, Text) void退出动画即将开始时触发的回调onExited(node?: null, Element, Text) void退出动画完成后触发的回调onExiting(node?: null, Element, Text) void退出动画开始时触发的回调timeoutnumber(300)动画过渡时长transitionAppearboolean首次渲染即显示时是否也播放进入动画unmountOnExitboolean退出后是否将组件从 DOM 中卸载5.3 源码原理Bounce.tsx 为Transition传入animation并绑定四组 classTransition {...propsWithDefaults} ref{ref} animation timeout{timeout} enteringClassName{prefix(bounce-in)} // rs-anim-bounce-in enteredClassName{prefix(bounce-in)} exitingClassName{prefix(bounce-out)} // rs-anim-bounce-out exitedClassName{prefix(bounce-out)} /样式定义在 styles/_bounce.scssbounceIn从opacity: 0; transform: scale(0.8)弹入至scale(1)bounceOut反向弹出弹性缓动曲线为cubic-bezier(0.68, -0.55, 0.27, 1.55)动画时长0.3s且fill-mode: forwards见 styles/_mixin.scss 中的animation-commonmixin。六、Animation.Slide滑动动画Animation.Slide支持从四个方向滑入滑出默认从右侧滑入常用于抽屉、侧边栏、通知浮层等场景。6.1 官方示例示例见 slide.md用一组按钮动态切换placementimport { Animation, Button, ButtonToolbar, Card } from rsuite; const AnimatedPanel React.forwardRef((props, ref) ( Card {...props} ref{ref} shaded bordered{false} w{240} h{120} cwhite bglinear-gradient(45deg, #4CAF50, #2196F3) div Card.HeaderSlide Animation/Card.Header Card.BodyThis panel demonstrates sliding transitions from different directions./Card.Body /div /Card )); const App () { const [show, setShow] React.useState(true); const [placement, setPlacement] React.useState(right); const onChange placement { setShow(!show); setPlacement(placement); }; return ( div ButtonToolbar Button appearanceprimary onClick{() onChange(left)}Slide Left/Button Button appearanceprimary onClick{() onChange(right)}Slide Right/Button Button appearanceprimary onClick{() onChange(top)}Slide Top/Button Button appearanceprimary onClick{() onChange(bottom)}Slide Bottom/Button /ButtonToolbar hr / div Animation.Slide in{show} placement{placement} {(props, ref) AnimatedPanel {...props} ref{ref} /} /Animation.Slide /div /div ); };6.2Animation.SlidePropsPropertyType(Default)DescriptionenteredClassNamestring组件进入动画完成之后添加的 classNameenteringClassNamestring组件开始进入动画时添加的 classNameexitedClassNamestring组件退出动画完成之后添加的 classNameexitingClassNamestring组件开始退出动画时添加的 classNameinboolean为 true 时显示组件并播放进入动画onEnter(node?: null, Element, Text) void进入动画开始前触发的回调onEntered(node?: null, Element, Text) void进入动画完成后触发的回调onEntering(node?: null, Element, Text) void进入动画开始时触发的回调onExit(node?: null, Element, Text) void退出动画即将开始时触发的回调onExited(node?: null, Element, Text) void退出动画完成后触发的回调onExiting(node?: null, Element, Text) void退出动画开始时触发的回调timeoutnumber(300)动画过渡时长transitionAppearboolean首次渲染即显示时是否也播放进入动画unmountOnExitboolean退出后是否将组件从 DOM 中卸载placementPlacement(right)组件的放置方向其中placement的类型定义与 docs/pages/_common/types/placement4.md 一致type Placement top | bottom | right | left;6.3 源码原理Slide.tsx 根据placement动态拼接 classconst enterClassName prefix(slide-in, placement); // rs-anim-slide-in-right const exitClassName prefix(slide-out, placement); // rs-anim-slide-out-right样式见 styles/_slide.scss.rs-anim-slide-out使用 Fast out 缓动cubic-bezier(0.4, 0, 1, 1).rs-anim-slide-in使用ease-in-outright/left/top/bottom四个方向分别映射slideInRight/slideOutRight、slideInLeft/slideOutLeft、slideInTop/slideOutTop、slideInBottom/slideOutBottom四组 keyframes。特别值得一提的是源码对 RTL 做了适配当文档方向为[dirrtl]时right与left的滑入滑出动画自动互换保证在从右到左的语言环境下滑动方向依然符合直觉。七、Animation.Transition完全自定义动画当内置的四种动画无法满足需求时Animation.Transition允许你通过指定四组 className 接入任意自定义 CSS animation实现 Zoom、Flip、Rotate 等任意效果。官方做法是在Transition上配置以下 classNameexitedClassNamecustom-exited exitingClassNamecustom-exiting enteredClassNamecustom-entered enteringClassNamecustom-entering7.1 官方示例多效果切换transition.md 中的示例定义了 Zoom、Flip、Rotate、Bounce 四套keyframes并通过effect状态拼接出每一套专属的 classimport { Animation, Button, ButtonToolbar, Card } from rsuite; const AnimatedPanel React.forwardRef(({ ...props }, ref) ( Card {...props} ref{ref} shaded bordered{false} w{240} h{120} cwhite bglinear-gradient(45deg, #4CAF50, #2196F3) div Card.HeaderCustom Transition/Card.Header Card.BodyClick different buttons to see various animation effects!/Card.Body /div /Card )); const App () { const [show, setShow] React.useState(true); const [effect, setEffect] React.useState(zoom); const onChange newEffect { setShow(!show); setEffect(newEffect); }; return ( div Styles / ButtonToolbar Button appearanceprimary onClick{() onChange(zoom)}Zoom/Button Button appearanceprimary onClick{() onChange(flip)}Flip/Button Button appearanceprimary onClick{() onChange(rotate)}Rotate/Button Button appearanceprimary onClick{() onChange(bounce)}Bounce/Button /ButtonToolbar hr / div Animation.Transition exitedClassName{custom-exited custom-${effect}-exited} exitingClassName{custom-exiting custom-${effect}-exiting} enteredClassName{custom-entered custom-${effect}-entered} enteringClassName{custom-entering custom-${effect}-entering} in{show} {(props, ref) AnimatedPanel {...props} ref{ref} /} /Animation.Transition /div /div ); };配套的样式模板定义了动画基础节奏与四套效果节选.custom-exiting, .custom-entering { animation: 0.5s cubic-bezier(0.4, 0, 0.2, 1); animation-fill-mode: forwards; } /* Zoom 效果 */ .custom-zoom-exiting { animation-name: zoomOut; } .custom-zoom-entering { animation-name: zoomIn; } keyframes zoomIn { from { opacity: 0; transform: scale3d(0.3, 0.3, 0.3); } 50% { opacity: 1; } } keyframes zoomOut { from { opacity: 1; } 50% { opacity: 0; transform: scale3d(0.3, 0.3, 0.3); } to { opacity: 0; } } /* Flip 效果 */ .custom-flip-exiting { animation-name: flipOut; } .custom-flip-entering { animation-name: flipIn; } keyframes flipIn { from { opacity: 0; transform: perspective(400px) rotate3d(1, 0, 0, 90deg); } 40% { transform: perspective(400px) rotate3d(1, 0, 0, -20deg); } 60% { opacity: 1; transform: perspective(400px) rotate3d(1, 0, 0, 10deg); } 80% { transform: perspective(400px) rotate3d(1, 0, 0, -5deg); } to { transform: perspective(400px); } } keyframes flipOut { from { transform: perspective(400px); } 30% { opacity: 1; transform: perspective(400px) rotate3d(1, 0, 0, -20deg); } to { opacity: 0; transform: perspective(400px) rotate3d(1, 0, 0, 90deg); } } /* Rotate 效果 */ .custom-rotate-exiting { animation-name: rotateOut; } .custom-rotate-entering { animation-name: rotateIn; } keyframes rotateIn { from { opacity: 0; transform: rotate3d(0, 0, 1, -180deg) scale(0.3); } 50% { opacity: 1; } } keyframes rotateOut { from { opacity: 1; } to { opacity: 0; transform: rotate3d(0, 0, 1, 180deg) scale(0.3); } } /* Bounce 效果 */ .custom-bounce-exiting { animation-name: bounceOut; } .custom-bounce-entering { animation-name: bounceIn; } keyframes bounceIn { from { opacity: 0; transform: scale3d(0.3, 0.3, 0.3); } 20% { transform: scale3d(1.1, 1.1, 1.1); } 40% { transform: scale3d(0.9, 0.9, 0.9); } 60% { opacity: 1; transform: scale3d(1.03, 1.03, 1.03); } 80% { transform: scale3d(0.97, 0.97, 0.97); } to { opacity: 1; transform: scale3d(1, 1, 1); } } keyframes bounceOut { 20% { transform: scale3d(0.9, 0.9, 0.9); } 50%, 55% { opacity: 1; transform: scale3d(1.1, 1.1, 1.1); } to { opacity: 0; transform: scale3d(0.3, 0.3, 0.3); } } .custom-entered { opacity: 1; } .custom-exited { opacity: 0; }7.2Animation.TransitionPropsPropertyType(Default)DescriptionenteredClassNamestring组件进入动画完成之后添加的 classNameenteringClassNamestring组件开始进入动画时添加的 classNameexitedClassNamestring组件退出动画完成之后添加的 classNameexitingClassNamestring组件开始退出动画时添加的 classNameinboolean为 true 时显示组件并播放进入动画onEnter(node?: null, Element, Text) void进入动画开始前触发的回调onEntered(node?: null, Element, Text) void进入动画完成后触发的回调onEntering(node?: null, Element, Text) void进入动画开始时触发的回调onExit(node?: null, Element, Text) void退出动画即将开始时触发的回调onExited(node?: null, Element, Text) void退出动画完成后触发的回调onExiting(node?: null, Element, Text) void退出动画开始时触发的回调timeoutnumber(1000)动画过渡时长transitionAppearboolean首次渲染即显示时是否也播放进入动画unmountOnExitboolean退出后是否将组件从 DOM 中卸载需要注意Transition的默认timeout为1000ms见 Transition.tsx 的defaultProps与其余四个子组件默认 300ms 不同自定义动画通常需要更充裕的兜底时间。八、通用行为与最佳实践8.1 回调执行顺序测试验证Transition的回调有严格的时序进入时依次为onEnter → onEntering → onEntered退出时依次为onExit → onExiting → onExited。这一行为由 Transition.spec.tsx 中的单元测试验证测试分别断言了三个进入回调与三个退出回调都会按序被调用。8.2 transitionAppear 的取舍transitionAppear控制首次渲染且in为 true 时是否也要播放进入动画不开启默认组件初始即显示不播放动画避免页面加载时出现多余的闪烁开启挂载时执行一次完整的进入动画适合弹窗、通知等出现即强调的场景。源码层面构造函数中props.in props.transitionAppear时初始状态为STATUS.EXITED随后在componentDidMount中调用performEnter播放进入动画测试用例 Transition.spec.tsx 验证了transitionAppear下onEntered会在动画结束后才触发。rsuite 的 Modal 遮罩层Modal.tsx正是通过Fade transitionAppear实现弹窗打开时的淡入效果。8.3 unmountOnExit 与性能开启unmountOnExit后退出动画完成时组件会进入UNMOUNTED状态并返回null不再渲染。这在列表渲染大量隐藏节点时能显著减少 DOM 数量。但其代价是每次显示都需要重新挂载子树因此对频繁开合、内部有重状态的内容需权衡使用。8.4 与内置组件的配合Animation系列组件已深度集成进 rsuite 自身除上述 Modal 遮罩 使用Fade外Ripple 水波纹 也使用Transition in{rippling} enteringClassName{prefix(rippling)} onEntered{handleRippled}驱动点击波纹扩散动画。你可以参考这些内部用法在自己的业务组件中做同样的集成。九、小结选型速查淡入淡出用Fade收放面板用Collapsedimension切换横/纵强调提示用Bounce方向性滑动用Slideplacement选方向任何其他效果用Transition 自定义keyframes。统一心智模型五个组件共享同一套五态状态机 四阶段 className 六事件回调 timeout 兜底的架构学会一个就等于学会了全部。实战建议需要精确控制出现时机请开启transitionAppear隐藏内容占位可开启unmountOnExit自定义动画务必保证 CSSanimation-fill-mode与Transition的timeout兜底时间匹配避免状态机卡在中间态。更多源码级细节可继续阅读 src/Animation/Transition.tsx、src/Animation/Collapse.tsx、src/Animation/styles/index.scss 以及测试目录 src/Animation/test。赞分享前端UI组件【免费下载链接】rsuite A suite of React components .项目地址https://gitcode.com/gh_mirrors/rs/rsuite点击查看免费下载相关推荐Element UI 内置过渡动画实战fade、zoom 与 el-collapse-transition 详解Element UI 内置过渡动画实战fade、zoom 与 el collapse transition 详解 Element UIElement除了提前端UI组件设计系统CANN数学算子BesselI0e函数BesselI0e 产品支持情况 | 产品 | 是否支持 | |: | : : | | term Ascend 950PR/Ascend 950DT/ter算子库人工智能CANNElement Plus 内置过渡动画完全指南Fade、Zoom 与 Collapse Transition 的原理与实战Element Plus 内置过渡动画完全指南Fade、Zoom 与 Collapse Transition 的原理与实战 Element Plus 在官方文前端UI组件上一篇Nix Build Trace构建追踪深度解析以解析后 Derivation 为键的构建记忆化表下一篇misakaX解锁iOS系统深度定制的技术实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

nRF52840 Dongle + Wireshark:BLE抓包实战方案全解析

nRF52840 Dongle + Wireshark:BLE抓包实战方案全解析

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

2026/9/25 4:33:30 阅读更多 →
PX4与ROS2通信实战:Micro XRCE-DDS从架构到联调

PX4与ROS2通信实战:Micro XRCE-DDS从架构到联调

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

2026/9/25 4:33:30 阅读更多 →
C语言开根号全解析:sqrt、pow与嵌入式实现方案

C语言开根号全解析:sqrt、pow与嵌入式实现方案

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

2026/9/25 4:33:30 阅读更多 →

最新新闻

深入理解 Sinon 的 `spyCall.firstArg`:读取单次调用首个参数的正确姿势

深入理解 Sinon 的 `spyCall.firstArg`:读取单次调用首个参数的正确姿势

测试开发工具 【免费下载链接】sinon Test spies, stubs and mocks for JavaScript. 项目地址: https://gitcode.com/gh_mirrors/si/sinon 点击查看 免费下载 spyCall.firstArg 是 Sinon 中 spy call 对象的一个核心只读属性,用于获取某一次函数调用传入…

2026/9/25 4:57:52 阅读更多 →
腾讯云WorkBuddy Enterprise企业级AI Agent平台架构与实操指南

腾讯云WorkBuddy Enterprise企业级AI Agent平台架构与实操指南

1. 从零理解 WorkBuddy Enterprise 的定位与核心价值1.1 这个平台到底解决什么问题WorkBuddy Enterprise 是腾讯云推出的一套企业级 AI 平台与 Agent 生态产品。说白了,它要解决的核心问题是:企业想用 AI,但不知道怎么把 AI 能力安全、可控、…

2026/9/25 4:57:52 阅读更多 →
Endnote在Word中消失?COM加载项排查与修复指南

Endnote在Word中消失?COM加载项排查与修复指南

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

2026/9/25 4:57:52 阅读更多 →
Java图书管理系统SWT实战:从环境搭建到避坑指南

Java图书管理系统SWT实战:从环境搭建到避坑指南

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

2026/9/25 4:57:52 阅读更多 →
GDS版图从入门到精通:层次结构、生成流程与-uniquifycellnames避坑指南

GDS版图从入门到精通:层次结构、生成流程与-uniquifycellnames避坑指南

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

2026/9/25 4:57:52 阅读更多 →
Navicat免安装版深度解析:依赖库、配置与MySQL连接排查指南

Navicat免安装版深度解析:依赖库、配置与MySQL连接排查指南

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

2026/9/25 4:56:51 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →