# 修复多列布局与联系表单渲染问题
## 1。问题背景
在可视化拖拽编辑器中,**多列布局组件**和**联系表单组件**存在以下问题:
| 问题 | 表现 |
|------|------|
| 多列布局无法保存列数据 | 右侧属性面板没有列编辑字段,只能保存标题 |
| 联系表单后台不显示 | 前台页面显示「组件开发中」,`renderContactForm` 未被调用 |
---
## 2。修复内容
### 2.1 修复联系表单渲染
**问题原因**:`renderComponent` 方法中,`contact_form` 类型被错误映射为 `renderContact_form`,与实际方法名 `renderContactForm` 不匹配。
**文件路径**:`app/Services/PageRenderService.php`
**修改前**:
```php
protected function renderComponent(PageComponent $component): string
{
$method = 'render' . ucfirst($component->component_type);
// contact_form 变成 renderContact_form,方法不存在
}
```
**修改后**:
```php
protected function getRenderMethod(string $type): string
{
$map = [
'contact_form' => 'renderContactForm',
'multi_col' => 'renderMultiCol',
];
return $map[$type] ?? 'render' . ucfirst($type);
}
protected function renderComponent(PageComponent $component): string
{
$method = $this->getRenderMethod($component->component_type);
// ...
}
```
### 2.2 修复多列布局编辑功能
**问题原因**:右侧属性面板没有为多列布局提供列编辑字段,导致无法保存列数据。
**文件路径**:`resources/js/admin/views/PageEditor.vue`
**新增内容**:
**(1)模板中增加多列布局专用编辑区**
```vue
<template v-if="selectedComponent.component_type === 'multi_col'">
<el-form-item label="列数">
<el-select v-model="columnCount" @change="resizeColumns">
<el-option :value="2" label="2列" />
<el-option :value="3" label="3列" />
<el-option :value="4" label="4列" />
</el-select>
</el-form-item>
<div v-for="(col, idx) in editForm.columns" :key="idx" style="border:1px solid #eee; padding:10px; margin-bottom:10px;">
<h4>第{{ idx+1 }}列</h4>
<el-form-item label="图片">
<el-input v-model="col.image_url" placeholder="图片URL" />
</el-form-item>
<el-form-item label="标题">
<el-input v-model="col.title" placeholder="列标题" />
</el-form-item>
<el-form-item label="内容">
<el-input type="textarea" v-model="col.content" rows="3" placeholder="列内容" />
</el-form-item>
</div>
</template>
```
**(2)新增响应式变量和方法**
```typescript
const columnCount = ref(3);
const editForm = ref({
// ... 原有字段
columns: [] as any[],
});
const initColumns = () => {
const cols = [];
for (let i = 0; i < columnCount.value; i++) {
cols.push({ image_url: '', title: '', content: '' });
}
editForm.value.columns = cols;
};
const resizeColumns = () => initColumns();
```
**(3)修改 `watch` 监听,加载已保存的列数据**
```typescript
if (newVal.component_type === 'multi_col') {
const cols = newVal.content.columns || [];
columnCount.value = cols.length || 3;
editForm.value.columns = cols.length ? [...cols] : [
{ image_url: '', title: '列1', content: '内容1' },
{ image_url: '', title: '列2', content: '内容2' },
{ image_url: '', title: '列3', content: '内容3' },
];
}
```
**(4)修改 `saveComponent` 保存逻辑**
```typescript
let contentData: any = {};
if (selectedComponent.value.component_type === 'multi_col') {
contentData = { columns: editForm.value.columns };
} else {
contentData = {
title: editForm.value.title,
subtitle: editForm.value.subtitle,
text: editForm.value.text,
image_url: editForm.value.image_url,
link_url: editForm.value.link_url,
};
}
```
---
## 3。验证结果
| 验证项 | 预期结果 | 实际结果 |
|--------|---------|---------|
| 联系表单前台显示 | 显示完整表单(姓名、邮箱、留言、提交按钮) | ✅ |
| 多列布局列数选择 | 可选择2/3/4列 | ✅ |
| 多列布局列数据保存 | 每列的图片、标题、内容可编辑保存 | ✅ |
| 多列布局前台渲染 | 显示对应列数内容 | ✅ |