# 可视化拖拽编辑器
## 搭建编辑器三栏布局
### 1. 创建 PageEditor.vue
#### 1.1 文件路径
`resources\js\admin\views\PageEditor.vue`
#### 1.2 完整代码
```vue
<template>
<div>
<!-- 左侧:组件库 -->
<div>
<div>组件库</div>
<div>
<div>横幅 Banner</div>
<div>纯文本</div>
<div>图片</div>
<div>多列布局</div>
<div>地图</div>
<div>联系表单</div>
</div>
</div>
<!-- 中间:画布 -->
<div>
<div>页面画布</div>
<div>
<p>从左侧拖拽组件到这里</p>
</div>
</div>
<!-- 右侧:属性面板 -->
<div>
<div>属性面板</div>
<div>
<p>点击组件编辑属性</p>
</div>
</div>
</div>
</template>
<script setup>
// 编辑器逻辑后续添加
</script>
<style scoped>
.editor-container {
display: flex;
height: calc(100vh - 120px);
gap: 16px;
}
.editor-sidebar {
width: 260px;
background: #fff;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.editor-canvas {
flex: 1;
background: #fff;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.editor-property {
width: 320px;
background: #fff;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.sidebar-title,
.canvas-title,
.property-title {
padding: 16px;
font-weight: bold;
border-bottom: 1px solid #e8e8e8;
background: #fafafa;
}
.component-list {
padding: 16px;
display: flex;
flex-direction: column;
gap: 8px;
}
.component-item {
padding: 12px;
background: #f5f5f5;
border-radius: 6px;
cursor: move;
text-align: center;
transition: all 0.2s;
}
.component-item:hover {
background: #e6f7ff;
border-color: #1890ff;
}
.canvas-content,
.property-content {
flex: 1;
padding: 16px;
overflow-y: auto;
}
.empty-tip {
text-align: center;
color: #999;
padding: 40px;
}
</style>
```
#### 1.3 代码说明
| 代码 | 作用 |
|------|------|
| `display: flex; gap: 16px` | 三栏布局,左右固定宽度,中间自适应 |
| `cursor: move` | 鼠标悬停时显示可拖拽图标 |
| `empty-tip` | 空白区域提示文字 |
| `calc(100vh - 120px)` | 高度计算,减去顶部栏高度 |
---
### 2. 添加编辑器路由
#### 2.1 文件路径
`resources\js\admin\router\index.ts`
#### 2.2 修改内容
在 `children` 数组中,找到 `pages` 路由,在其后添加:
```typescript
{
path: 'pages/:id/edit',
name: 'page-editor',
component: () => import('../views/PageEditor.vue'),
},
```
#### 2.3 完整 children 部分
```typescript
children: [
{
path: '',
name: 'dashboard',
component: () => import('../views/Dashboard.vue'),
},
{
path: 'pages',
name: 'pages',
component: () => import('../views/Pages.vue'),
},
{
path: 'pages/:id/edit',
name: 'page-editor',
component: () => import('../views/PageEditor.vue'),
},
{
path: 'site',
name: 'site-settings',
component: () => import('../views/SiteSettings.vue'),
},
],
```
---
### 3. 修改页面管理编辑按钮
#### 3.1 文件路径
`resources\js\admin\views\Pages.vue`
#### 3.2 添加导入
```typescript
import { useRouter } from 'vue-router';
```
#### 3.3 添加 router 实例和修改 handleEdit
```typescript
const router = useRouter();
const handleEdit = (row: any) => {
router.push(`/admin/pages/${row.id}/edit`);
};
```
#### 3.4 修改说明
| 修改 | 作用 |
|------|------|
| `import { useRouter }` | 导入 Vue Router 的 useRouter 方法 |
| `const router = useRouter()` | 创建路由实例 |
| `router.push(...)` | 编程式导航,跳转到编辑器页面 |
---
### 4. 遇到的问题及解决
#### 4.1 问题:点击编辑按钮报错 `router is not defined`
| 项目 | 内容 |
|------|------|
| **现象** | 点击页面列表的「编辑」按钮,控制台报错 `router is not defined` |
| **原因** | `Pages.vue` 中没有导入 `useRouter` |
| **解决方案** | 添加 `import { useRouter } from 'vue-router'` 和 `const router = useRouter()` |
---
### 5. 编译验证
#### 5.1 执行命令
```bash
npm run build
```
#### 5.2 预期结果
编译成功,无报错。
---
### 6. 访问测试
#### 6.1 进入页面管理
浏览器打开:`http://engine-api.test/admin/pages`
#### 6.2 点击编辑
点击任意页面的「编辑」按钮
#### 6.3 预期结果
跳转到编辑器页面,显示三栏布局:
- 左侧:组件库(横幅 Banner、纯文本、图片等)
- 中间:页面画布(显示「从左侧拖拽组件到这里」)
- 右侧:属性面板(显示「点击组件编辑属性」)
---
### 7. 验证结果
| 验证项 | 预期结果 | 实际结果 |
|--------|---------|---------|
| 编译 | 无报错 | ✅ 通过 |
| 点击编辑按钮 | 跳转到编辑器页面 | ✅ 通过 |
| 左侧组件库 | 显示 6 个组件 | ✅ 通过 |
| 中间画布 | 显示提示文字 | ✅ 通过 |
| 右侧属性面板 | 显示提示文字 | ✅ 通过 |
| 三栏布局 | 左右固定宽度,中间自适应 | ✅ 通过 |