
前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载useNodeProps()是 OpenPencil 中属性面板Property Panel家族的底层助手组合式函数composableuseAppearance、useLayout、useTypography等高层组合式函数均建立在它之上。本文围绕它要解决的四个核心问题展开混合值mixed-value检测、多选节点批量更新、数组型属性fills / strokes / effects的条目编辑、以及支持撤销undo的预览 提交分离语义并结合open-pencil/vue源码剖析其底层实现。读完本文你将能够使用useNodeProps为自定义属性面板接入多选感知的状态与提交逻辑。为什么需要 useNodeProps在设计工具中属性面板总是要面对同一个复杂场景用户选中了一个节点或者同时选中了多个节点面板需要检测混合值——多个选中节点上同一属性取值不一致时面板应显示混合MIXED占位而不是某个节点的具体值批量更新——对多个选中节点同时应用同一个属性变更编辑数组属性——修改fills填充、strokes描边、effects效果数组中某一项或删除、切换某项的可见性撤销感知的提交——拖动数值时先实时预览不产生撤销记录松手时再统一提交为一条可撤销的历史条目。这些逻辑如果由每个面板重复实现会带来大量重复代码和一致性问题。OpenPencil 将它们集中到了packages/vue/src/controls/node-props/use.ts的useNodeProps()与packages/vue/src/controls/node-props/helpers.ts中并通过packages/vue/src/index.ts第 32 行对外导出useNodeProps与MIXED。使用场景判定原文档明确指出当你的自定义面板需要以下能力时应该使用useNodeProps()检测混合值mixed-value detection多选更新multi-selection updates数组条目编辑array-item editing撤销感知的属性提交undo-aware property commits。这些能力覆盖了几乎所有属性面板的底层需求。useNodeProps不关心具体是哪个属性域外观、布局还是排版它只负责选区状态 属性读写 撤销提交这一通用底座。API 速览useNodeProps()返回一组由选区派生的响应式状态与动作。以下是完整返回值列表对应 use.ts 的返回对象返回值类型/含义说明storeEditor编辑器实例来自useEditor()注入nodeRefSceneNode \| null当前激活节点单选时即选中节点nodesRefSceneNode[]当前选中的全部节点isMultiComputedRefboolean是否多选nodes.value.length 1activeComputedRefboolean是否存在可编辑选区有节点或多选activeNodeComputedRefSceneNode \| null单选的节点或多选时的第一个节点targetNodes() SceneNode[]数组动作实际作用的节点列表prop(key)ComputedRefMixedValueT某属性的合并merged值多选不一致时返回MIXEDmerged(key)MixedValueT非响应式的合并值读取函数updateAllWithUndo(patch, label)函数对全部选中节点批量打补丁并记入撤销updateArrayItem(key, index, patch, label)函数更新数组属性中某一项removeArrayItem(key, index, label)函数移除数组属性中某一项toggleArrayVisibility(key, index)函数切换数组条目visible标志isArrayMixed(key)boolean数组属性在多选中是否混合updateProp(key, value)函数实时更新scrub单属性不产生撤销记录commitProp(key, value, previous)函数提交属性变更写入撤销历史另外还导出了两个类型级能力MIXED哨兵符号表示多个节点取值不一致定义于 helpers.tsMixedValueTT | typeof MIXED的联合类型。混合值检测MIXED 哨兵与 merged混合值检测由createNodePropSelectionState实现。核心逻辑在 helpers.tsfunction mergedK extends keyof SceneNode(key: K): MixedValueSceneNode[K] { const all nodes.value if (all.length 0) return MIXED // 无选区 → 混合占位 const first all[0][key] for (let i 1; i all.length; i) { if (all[i][key] ! first) return MIXED // 任一节点不一致 → 混合占位 } return first }实现要点无选区时直接返回MIXED面板据此渲染占位状态多选时逐一比对第一个节点之后的每个节点只要有一处不一致就整体返回MIXEDprop(key)在此基础上包了一层computed()得到响应式的混合值引用可直接绑定到模板。数组属性的混合检测对于fills、strokes、effects这类数组属性普通的!比较无法捕获长度相同但内容不同的情况。isNodeArrayMixedhelpers.ts做了深度比较长度不同的数组直接判定混合长度相同的数组逐项调用areArrayItemsEqual递归比较支持嵌套对象与嵌套数组非数组属性则退回逐节点!比较。useNodeProps()将其暴露为isArrayMixed(key)面板可以据此决定是否禁用某项编辑或显示混合占位。多选批量更新updateAllWithUndoupdateAllWithUndo对nodes.value中每一个节点调用store.updateNodeWithUndo(n.id, patch, label)helpers.ts。底层实现位于 packages/core/src/editor/nodes.ts。updateNodeWithUndo的核心流程是通过styleDetachmentChanges、textAutoResizeChanges、pathTextEditChanges对补丁做二次处理例如路径文本的重排字形优先级pick出变更前每个被改动属性的旧值previousctx.graph.updateNode(id, nextChanges)应用新值并runLayoutForNode重排布局ctx.undo.push写入一条带label、包含forward/inverse的撤销记录ctx.requestRender()触发重绘。因此面板里一键把所有选中节点的不透明度设为 50%这类操作会自然产生一条可撤销的单一历史记录且撤销后布局会正确重排。数组条目编辑更新、删除与可见性切换createNodePropArrayActionshelpers.ts封装了三个数组操作全部作用于targetNodes()多选时为全部选中节点单选时为激活节点updateArrayItem更新第 index 项function updateArrayItem(key, index, patch, label) { for (const n of targetNodes()) { const arr [...n[key]] arr[index] { ...arr[index], ...patch } store.updateNodeWithUndo(n.id, { [key]: arr }, label) } }它通过不可变更新先拷贝数组再替换目标项保证不触发意外的响应式副作用例如修改填充颜色或描边线宽时可传入{ color: ... }这类局部补丁。removeArrayItem删除第 index 项用filter生成去掉目标项的新数组后提交同样经过updateNodeWithUndo因此删除操作可撤销。toggleArrayVisibility切换条目可见性对数组第index项翻转visible标志撤销标签固定为Toggle ${key} visibility。updateArrayItem与removeArrayItem的第三个/第二参数label会作为撤销记录的标签建议使用有语义的中文或英文描述例如Change fill方便用户在历史面板中识别。预览与提交分离updateProp / commitProp数值型控件拖动 scrub通常需要拖动过程中实时预览、松手时一次性提交为一条撤销记录。createNodePropScrubActionshelpers.ts实现了这套语义updateProp(key, value)只调用store.updateNode不带撤销记录用于拖动过程的实时预览多选时先用previousValuesMap 记录每个节点修改前的原始值避免后续提交时丢失各节点各自的起点commitProp(key, value, previous)调用store.commitNodeUpdate写入撤销历史多选时逐节点用各自记录的previous作为撤销逆操作的还原值提交后清空缓存。底层commitNodeUpdate定义于 packages/core/src/editor/undo.ts它会重新pick当前值若与还原值相等则跳过避免空撤销记录否则 push 一条forward/inverse成对的记录。注意undo.ts的commitNodeUpdate同时被 bridges/undo.ts 以undoActions.commitNodeUpdate的形式暴露给编辑器桥接层。因此一个典型的数值输入框可以这样接线const { updateProp, commitProp, prop } useNodeProps() // 拖动过程中实时预览不写撤销 updateProp(opacity, 0.6) // 松手时提交为一条可撤销记录 commitProp(opacity, 0.6, 0.5)多选场景下这套先记录旧值、再统一提交的设计保证每个节点都能正确回到各自的初始值而不是退回到某一个节点的旧值。在高层组合式函数中的应用useNodeProps是高层组合式函数的底座。例如useAppearancepackages/vue/src/controls/appearance/use.ts直接解构了nodes、node、active、isMulti、merged、updateProp、commitProp再叠加外观领域专属的createAppearanceState/createAppearanceActionsexport function useAppearance() { const editor useEditor() const { nodes, node, active, isMulti, merged, updateProp, commitProp } useNodeProps() const appearanceState createAppearanceState({ node, nodes, isMulti, merged, ... }) const appearanceActions createAppearanceActions({ editor, ... }) return { editor, nodes, node, active, isMulti, ...appearanceState, updateProp, commitProp, ...appearanceActions } }useLayoutpackages/vue/src/controls/layout/use.ts同样构建在选区状态之上只是它更多使用createLayoutSelectionState等布局专属 helper并在内部共享updateProp/commitProp的命名约定。从 SDK 架构文档 可以看出controls/目录中usePosition、useLayout、useAppearance、useTypography、useNodeProps、usePropScrub等组合式函数共同组成了属性面板的控制层open-pencil/vue只负责编辑器集成与无样式可复用的逻辑不持有编辑器模型本身。这种底层通用底座 领域专属动作的分层使得新增一个属性面板时只需关注领域逻辑多选、混合值、撤销等横切关注点全部由useNodeProps兜底。相关 APIuseAppearance——外观可见性、不透明度、圆角领域的面板组合式函数useLayout——布局flex/grid、尺寸、内边距、对齐、轨道领域的面板组合式函数useTypography——排版领域的面板组合式函数usePropScrub——更底层的拖动 scrub 提交辅助PropertyListRoot——属性列表的结构化根组件。赞分享前端桌面应用AI 应用MCP 服务【免费下载链接】open-pencilAI-native design editor. Open-source Figma alternative.项目地址https://gitcode.com/gh_mirrors/op/open-pencil点击查看免费下载相关推荐open-pencil SDK 深度解析useNodeProps 属性面板 Composable 的混合值检测、多选更新与撤销感知提交open pencil SDK 深度解析useNodeProps 属性面板 Composable 的混合值检测、多选更新与撤销感知提交 useNodeProp前端桌面应用AI 应用MCP 服务PaddleSpeech s2t frontend utility 模块全解词典、Manifest、CMVN 与音频数值处理的底层工具箱PaddleSpeech s2t frontend utility 模块全解词典、Manifest、CMVN 与音频数值处理的底层工具箱 导读 PaddleS人工智能语音音频CADmium底部面板属性编辑与历史记录CADmium底部面板属性编辑与历史记录 概述 CADmium作为一款现代化的浏览器端CADComputer Aided Design计算机辅助设计软件3D建模前端图形学WebAssembly桌面应用上一篇Windows 11终极瘦身指南免费开源工具让你的系统性能飙升51%下一篇在Mac桌面打造沉浸式音乐体验LyricsX 2.0深度解析与实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考