fix(editor): 使用属性面板中的源码删除样式无效

This commit is contained in:
roymondchen 2026-07-23 15:15:19 +08:00
parent 6919a0a0b1
commit cde0805292
2 changed files with 29 additions and 11 deletions

View File

@ -164,17 +164,25 @@ const submit = async (
};
if (v.style) {
Object.entries(v.style).forEach(([key, value]) => {
if (value !== '' && newValue.style) {
newValue.style[key] = value;
}
});
// 空字符串样式值表示「清除该样式」,需保留才能在 doUpdate 的 mergeWith 中覆盖旧值。
if (eventData) {
// 表单编辑:先过滤掉空字符串(避免表单默认空值污染 DSL),
// 再按 changeRecords 恢复被主动清空的字段。
Object.entries(v.style).forEach(([key, value]) => {
if (value !== '' && newValue.style) {
newValue.style[key] = value;
}
});
eventData?.changeRecords?.forEach((record) => {
if (record.propPath?.startsWith('style') && record.value === '') {
setValueByKeyPath(record.propPath, record.value, newValue);
}
});
eventData.changeRecords?.forEach((record) => {
if (record.propPath?.startsWith('style') && record.value === '') {
setValueByKeyPath(record.propPath, record.value, newValue);
}
});
} else {
// 源码编辑器保存(无 eventData):style 原样保留,其中的空字符串视为用户主动清除该样式。
newValue.style = { ...v.style };
}
}
// 区分操作途径:表单字段编辑(MForm @change)会带上 eventData(含 changeRecords);

View File

@ -95,7 +95,7 @@ vi.mock('@editor/layouts/props-panel/FormPanel.vue', () => ({
// 模拟 CodeEditor 源码保存:仅传 values,无 eventData、无 error(对应 saveCode 路径)
h('button', {
class: 'code-save-btn',
onClick: () => emit('submit', { id: 'n1', style: { color: 'red' } }),
onClick: () => emit('submit', { id: 'n1', style: { color: 'red', width: '' } }),
}),
h('button', { class: 'submit-err-btn', onClick: () => emit('submit-error', new Error('e')) }),
h('button', { class: 'form-err-btn', onClick: () => emit('form-error', new Error('e')) }),
@ -239,6 +239,16 @@ describe('PropsPanel', () => {
expect(options.historySource).toBe('code');
});
test('CodeEditor 源码保存时 style 中的空字符串值被保留(表示清除该样式)', async () => {
const wrapper = mount(PropsPanel, { props: {} as any });
await new Promise((r) => setTimeout(r, 0));
await wrapper.find('.code-save-btn').trigger('click');
const calledNode = (editorService.update.mock.calls[0] as any)[0];
expect(calledNode.style.color).toBe('red');
expect(calledNode.style.width).toBe('');
});
test('mounted 事件 emit', async () => {
const wrapper = mount(PropsPanel, { props: {} as any });
await wrapper.find('.mounted-btn').trigger('click');