如何让WordPress自定义区块的save.js保存多个属性?
WordPress 区块多属性保存验证错误的解决方法
问题场景
使用@wordpress/create-block构建自定义区块时,定义了theNotes和theContact两个字符串属性,在edit.js中通过两个TextControl分别绑定属性值,但save.js保存后出现区块验证错误:save函数生成的内容里两个div的文本值重复,均为两个属性值的拼接结果,而文章主体中实际存储的是各自独立的值。
错误示例:
save函数生成的内容: <div class="wp-block-create-block-editor-notes"><div>notesTestcontactTest</div><div>notesTestcontactTest</div></div> 从文章主体获取的内容: <div class="wp-block-create-block-editor-notes"><div>notesTest</div><div>contactTest</div></div>
错误原因
问题出在block.json的属性定义中,两个属性的selector都设置为"div"。WordPress解析区块内容时,会把所有匹配该selector的元素文本内容拼接起来,赋值给每个使用该selector的属性,导致theNotes和theContact都拿到了所有div的文本总和,最终save时生成重复内容,触发验证错误。
修复方案
为每个属性指定唯一的selector,通过给保存后的DOM元素添加类名,让WordPress能够准确匹配每个属性对应的元素。
修改后的代码示例
1. 更新block.json的属性定义
"attributes": { "theNotes": { "type": "string", "source": "text", "selector": ".notes-container", "default": "" }, "theContact": { "type": "string", "source": "text", "selector": ".contact-container", "default": "" } }
2. 修改save.js的保存结构
给每个属性对应的div添加类名,与block.json中的selector对应:
export default function save( { attributes } ) { const blockProps = useBlockProps.save(); return ( <div { ...blockProps }> <div className="notes-container">{ attributes.theNotes }</div> <div className="contact-container">{ attributes.theContact }</div> </div> ); }
3. 可选:同步edit.js的结构(非必须,但更规范)
给编辑界面中的容器div也添加对应类名,保持前后端结构一致:
export default function Edit( { attributes, setAttributes } ) { return ( <div { ...useBlockProps() }> <div className="notes-container"> <TextControl label={ __( 'The Notes', 'editor-notes' ) } value={ attributes.theNotes } onChange={ ( val ) => setAttributes( { theNotes: val } ) } /> </div> <div className="contact-container"> <TextControl label={ __( 'The Contact', 'editor-notes' ) } value={ attributes.theContact } onChange={ ( val ) => setAttributes( { theContact: val } ) } /> </div> </div> );}
原理说明
每个属性需要唯一的selector来匹配DOM元素,这样WordPress在解析区块内容时,能准确提取对应元素的文本值赋值给属性,避免不同属性的内容混淆。修改后,save函数生成的内容与文章主体存储的内容完全一致,区块验证即可通过。
内容的提问来源于stack exchange,提问作者red5
相关产品推荐
相关产品推荐

