搜索

📄 文章 📚 合集
热门搜索
🐘 PHP ⚡ Laravel 🎨 Vue.js ⚛️ React 📦 Yii 📘 JavaScript 🗄️ MySQL 🐳 Docker
返回合集

[板块5:静态页面生成器] - 15 - 修复多列布局与联系表单渲染问题

代码示例
# 修复多列布局与联系表单渲染问题

## 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列 | ✅ |
| 多列布局列数据保存 | 每列的图片、标题、内容可编辑保存 | ✅ |
| 多列布局前台渲染 | 显示对应列数内容 | ✅ |

🧸 adorable code

专注 PHP、JavaScript、Laravel、Vue.js、React、Yii 全栈开发。记录技术探索过程中的灵感与经验,分享工程实践洞见。

hello@adorablecode.com