ax-drag-ui
v0.0.30
Published
本项目支持通过**组件面板(ComponentPanel.vue)中的 commonData 配置**,结合 `widgetsConfig.js` 的属性-编辑器映射,实现拖拽组件到画布后,右侧属性面板自动渲染你配置的所有属性,极大提升属性配置的灵活性和可维护性。
Readme
低代码设计器属性面板配置与渲染说明
本项目支持通过组件面板(ComponentPanel.vue)中的 commonData 配置,结合 widgetsConfig.js 的属性-编辑器映射,实现拖拽组件到画布后,右侧属性面板自动渲染你配置的所有属性,极大提升属性配置的灵活性和可维护性。
---https://mobile.yangkeduo.com/goods.html?goods_id=429422443186
1. 属性配置方式
- 在
ComponentPanel.vue文件中,commonData变量用于定义可拖拽的组件及其属性:
const commonData = [
{
name: '主要按钮',
description: '用于主要操作',
type: 'button',
text: '主要按钮',
size: 'middle',
shape: '',
icon: '',
disabled: false,
loading: false,
// ... 你想让属性面板可编辑的属性都可以在这里配置
style: {}
},
// 可继续添加更多组件
]- 你可以为每个组件配置任意属性,只要在
widgetsConfig.js里有对应的映射即可自动渲染。
2. 属性-编辑器映射(widgetsConfig.js)
- 在
widgetsConfig.js中,维护属性名与编辑器组件的映射关系:
export const buttonTypes = [
{ prop: 'text', editor: 'TextEditor' },
{ prop: 'type', editor: 'TypeEditor' },
{ prop: 'size', editor: 'SizeEditor' },
{ prop: 'shape', editor: 'ShapeEditor' },
{ prop: 'icon', editor: 'IconEditor' },
{ prop: 'disabled', editor: 'DisabledEditor' },
{ prop: 'loading', editor: 'LoadingEditor' },
// ... 其他属性
]- 每个 editor 组件放在
src/property-panel/property-editor/目录下,命名需与 editor 字段一致。
3. 拖拽与属性面板自动渲染流程
- 拖拽组件:在组件面板拖拽 commonData 中的组件到画布。
- 数据结构:拖拽时,组件的所有属性会被平铺存储到 store 的 components 数组中。
- 选中组件:点击画布中的组件,store.selectedComponents 会同步选中 id。
- 属性面板渲染:
- 属性面板会遍历 commonData 配置的属性,
- 通过 widgetsConfig.js 查找对应的编辑器组件,
- 自动渲染所有可编辑属性,顺序和内容与 commonData 完全一致。
4. 支持多组件扩展
- 只需在 commonData 中添加更多组件对象,并在 widgetsConfig.js 中补充属性-编辑器映射。
- 每个属性只要有对应的编辑器组件文件即可自动渲染。
- 支持不同类型组件的属性差异化配置。
5. 典型用例示例
组件面板配置
const commonData = [
{
name: '主要按钮',
description: '用于主要操作',
type: 'button',
text: '主要按钮',
size: 'middle',
shape: '',
icon: '',
disabled: false,
loading: false,
style: {}
},
{
name: '单选',
description: '用于单选操作',
type: 'single',
value: '',
label: '单选项',
options: [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' },
{ label: '选项3', value: '3' }
],
size: 'middle',
direction: 'horizontal',
optionType: 'default',
disabled: false,
required: false
},
{
name: '多选',
description: '用于多选操作',
type: 'checkbox',
value: [],
label: '多选项',
options: [
{ label: '选项1', value: '1' },
{ label: '选项2', value: '2' },
{ label: '选项3', value: '3' }
],
layout: 'list',
direction: 'vertical',
showSelectAll: true,
showSelectedCount: true,
maxCount: 0,
disabled: false,
required: false
}
]widgetsConfig.js 映射
export const buttonTypes = [
{ prop: 'text', editor: 'TextEditor' },
{ prop: 'type', editor: 'TypeEditor' },
{ prop: 'size', editor: 'SizeEditor' },
{ prop: 'shape', editor: 'ShapeEditor' },
{ prop: 'icon', editor: 'IconEditor' },
{ prop: 'disabled', editor: 'DisabledEditor' },
{ prop: 'loading', editor: 'LoadingEditor' }
]
// 单选组件属性映射
export const singleTypes = [
{ prop: 'value', editor: 'TextEditor' },
{ prop: 'label', editor: 'TextEditor' },
{ prop: 'description', editor: 'TextEditor' },
{ prop: 'required', editor: 'DisabledEditor' },
{ prop: 'disabled', editor: 'DisabledEditor' },
{ prop: 'options', editor: 'TextEditor' },
{ prop: 'size', editor: 'SizeEditor' },
{ prop: 'direction', editor: 'TextEditor' },
{ prop: 'optionType', editor: 'TextEditor' },
{ prop: 'buttonStyle', editor: 'TextEditor' },
{ prop: 'color', editor: 'ColorEditor' },
{ prop: 'backgroundColor', editor: 'BgColorEditor' },
{ prop: 'borderColor', editor: 'BorderColorEditor' },
{ prop: 'fontSize', editor: 'FontSizeEditor' },
{ prop: 'fontWeight', editor: 'FontWeightEditor' },
{ prop: 'labelAlign', editor: 'LabelAlignEditor' },
{ prop: 'borderRadius', editor: 'BorderRadiusEditor' },
{ prop: 'width', editor: 'WidthEditor' },
{ prop: 'height', editor: 'HeightEditor' },
{ prop: 'padding', editor: 'TextEditor' },
{ prop: 'margin', editor: 'TextEditor' }
]
// 多选组件属性映射
export const checkboxTypes = [
{ prop: 'value', editor: 'TextEditor' },
{ prop: 'label', editor: 'TextEditor' },
{ prop: 'description', editor: 'TextEditor' },
{ prop: 'required', editor: 'DisabledEditor' },
{ prop: 'disabled', editor: 'DisabledEditor' },
{ prop: 'checkboxOptions', editor: 'TextEditor' },
{ prop: 'layout', editor: 'TextEditor' },
{ prop: 'direction', editor: 'TextEditor' },
{ prop: 'columnsPerRow', editor: 'NumberEditor' },
{ prop: 'showSelectAll', editor: 'DisabledEditor' },
{ prop: 'selectAllText', editor: 'TextEditor' },
{ prop: 'showSelectedCount', editor: 'DisabledEditor' },
{ prop: 'maxCount', editor: 'NumberEditor' },
{ prop: 'minCount', editor: 'NumberEditor' },
{ prop: 'color', editor: 'ColorEditor' },
{ prop: 'backgroundColor', editor: 'BgColorEditor' },
{ prop: 'borderColor', editor: 'BorderColorEditor' },
{ prop: 'fontSize', editor: 'FontSizeEditor' },
{ prop: 'fontWeight', editor: 'FontWeightEditor' },
{ prop: 'labelAlign', editor: 'LabelAlignEditor' },
{ prop: 'borderRadius', editor: 'BorderRadiusEditor' },
{ prop: 'width', editor: 'WidthEditor' },
{ prop: 'height', editor: 'HeightEditor' },
{ prop: 'checkboxGap', editor: 'NumberEditor' }
]属性面板自动渲染
- 拖拽组件到画布,点击选中后,右侧属性面板会自动渲染 commonData 配置的所有属性,并支持编辑。
- 只需维护 commonData 和 widgetsConfig.js,无需手动修改属性面板代码。
6. 单选组件 (Single.vue) 特性说明
6.1 基础功能
- 单选选择: 基于 Ant Design Vue 的 Radio 组件,支持单选功能
- 动态选项: 支持通过配置动态设置选项内容
- 数据绑定: 完整的 v-model 支持,实现双向数据绑定
- 表单验证: 支持必填验证和错误提示
6.2 样式配置
- 显示模式: 支持默认圆形按钮和按钮样式两种模式
- 排列方向: 支持水平排列和垂直排列
- 尺寸控制: 提供 small、middle、large 三种尺寸
- 颜色定制: 支持自定义文字颜色、背景色、边框色
- 字体设置: 可配置字体大小、粗细、对齐方式
6.3 布局属性
- 容器尺寸: 支持设置组件宽度、高度
- 间距控制: 可配置内边距、外边距
- 边框样式: 支持圆角、边框颜色等设置
- 标签样式: 独立的标签样式配置,包括宽度、颜色、字体
6.4 交互功能
- 禁用状态: 支持整体禁用或单个选项禁用
- 必填标识: 支持必填项标识和验证
- 描述信息: 可添加组件描述文本
- 事件处理: 完整的 change 事件支持
6.5 使用示例
<template>
<Single
v-model="selectedValue"
label="请选择您的偏好"
:options="[
{ label: '选项A', value: 'a' },
{ label: '选项B', value: 'b' },
{ label: '选项C', value: 'c' }
]"
size="middle"
direction="horizontal"
optionType="default"
required
@change="handleChange"
/>
</template>7. 多选组件 (Multiple.vue) 特性说明
7.1 基础功能
- 多选功能: 基于 Ant Design Vue 的 Checkbox 组件,支持多选功能
- 动态选项: 支持通过配置动态添加、删除选项
- 数据绑定: 完整的 v-model 支持,实现双向数据绑定
- 全选支持: 内置全选/取消全选功能
7.2 高级特性
- 选项管理: 支持在属性面板中添加、删除选项
- 布局模式: 支持列表布局和网格布局两种模式
- 排列方向: 支持水平排列和垂直排列
- 数量限制: 支持最大/最小选择数量限制
- 选中计数: 可显示当前选中的项目数量
7.3 样式配置
- 网格布局: 支持自定义每行显示列数
- 间距控制: 可配置复选框之间的间距
- 颜色定制: 支持自定义文字颜色、背景色、边框色
- 字体设置: 可配置字体大小、粗细、对齐方式
- 标签样式: 独立的标签样式配置
7.4 交互功能
- 全选控制: 支持全选/取消全选按钮
- 禁用状态: 支持整体禁用或单个选项禁用
- 必填验证: 支持必填项标识和验证
- 属性联动: 所有属性支持实时修改和预览
7.5 使用示例
<template>
<Multiple
v-model="selectedValues"
label="请选择您的兴趣爱好"
:checkboxOptions="[
{ label: '音乐', value: 'music' },
{ label: '电影', value: 'movie' },
{ label: '运动', value: 'sport' },
{ label: '阅读', value: 'reading' }
]"
layout="grid"
:columnsPerRow="2"
direction="vertical"
:showSelectAll="true"
:showSelectedCount="true"
:maxCount="3"
required
@change="handleChange"
/>
</template>7.6 高级配置
- 选项数据格式:
{ label: '显示文本', value: '值', disabled: false } - 布局选项:
list(列表) 或grid(网格) - 方向选项:
horizontal(水平) 或vertical(垂直) - 数量限制:
maxCount最大选择数,minCount最小选择数 - 全选功能:
showSelectAll显示全选按钮,selectAllText自定义全选文本
8. 画布JSON获取和HTML转换功能
8.1 功能概述
新增了画布JSON数据获取和JSON转HTML的功能,支持将设计器中的组件配置导出为JSON格式,并转换为可预览的HTML代码。
8.2 核心方法
8.2.1 获取画布JSON数据
// 在CanvasArea组件中调用
const canvasJSON = canvasRef.getCanvasJSON()返回数据结构:
{
"components": [
{
"id": "组件唯一ID",
"type": "组件类型",
"name": "组件名称",
"x": 100,
"y": 200,
"width": 120,
"height": 40,
"zIndex": 1,
"style": {},
"options": {
"text": "按钮文本",
"type": "primary",
"size": "middle"
}
}
],
"metadata": {
"version": "1.0.0",
"exportTime": "2024-01-01T00:00:00.000Z",
"componentCount": 5,
"canvasHeight": 600,
"zoom": 1
}
}8.2.2 JSON转HTML
// 将JSON数据转换为HTML代码
const htmlCode = canvasRef.jsonToHTML(canvasJSON)生成的HTML特点:
- 保持组件的绝对定位布局
- 包含完整的样式信息
- 支持所有组件类型的渲染
- 生成标准的HTML结构
8.3 支持的组件类型
8.3.1 基础组件
- 按钮 (button): 支持文本、类型、尺寸、禁用状态等
- 输入框 (input): 支持占位符、值、禁用状态等
- 文本 (string): 支持文本内容、字体大小、颜色等
8.3.2 选择组件
- 单选 (single): 支持标签、选项列表、选中值等
- 多选 (checkbox): 支持标签、选项列表、多选值等
8.3.3 特殊组件
- 人员选择 (person): 支持标签、占位符等
- 部门选择 (department): 支持标签、占位符等
- 数字输入 (number): 支持标签、占位符、数值等
- 创建时间 (created): 支持标签、时间值等
- 更新时间 (updated): 支持标签、时间值等
- 超链接 (hyperlink): 支持文本、链接地址等
- 时间戳 (timestamp): 支持标签、时间值等
- 附件 (attachment): 支持标签、占位符等
- 日期范围 (dateRangePicker): 支持标签、占位符等
8.4 使用示例
8.4.1 在Vue组件中使用
<template>
<div>
<AxDrag ref="axDragRef" />
<button @click="exportData">导出数据</button>
<button @click="generateHTML">生成HTML</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import AxDrag from './packages/components/ax-drag/src/ax-drag.vue'
const axDragRef = ref(null)
const exportData = () => {
const canvasRef = axDragRef.value.$refs.canvasArea
if (canvasRef) {
const jsonData = canvasRef.getCanvasJSON()
console.log('画布JSON数据:', jsonData)
// 可以保存到文件或发送到服务器
const jsonString = JSON.stringify(jsonData, null, 2)
const blob = new Blob([jsonString], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'canvas-design.json'
a.click()
URL.revokeObjectURL(url)
}
}
const generateHTML = () => {
const canvasRef = axDragRef.value.$refs.canvasArea
if (canvasRef) {
const jsonData = canvasRef.getCanvasJSON()
const htmlCode = canvasRef.jsonToHTML(jsonData)
console.log('生成的HTML:', htmlCode)
// 可以保存HTML文件或预览
const htmlContent = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>画布设计预览</title>
<style>
body { margin: 0; padding: 20px; font-family: Arial, sans-serif; }
.design-container { position: relative; width: 100%; min-height: 600px; }
.canvas-component { position: absolute; }
</style>
</head>
<body>
${htmlCode}
</body>
</html>`
const blob = new Blob([htmlContent], { type: 'text/html' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'canvas-design.html'
a.click()
URL.revokeObjectURL(url)
}
}
</script>8.4.2 测试页面使用
项目提供了完整的测试页面 test-canvas-json-html.html,包含以下功能:
- 获取画布JSON: 获取当前画布的所有组件数据
- JSON转HTML: 将JSON数据转换为HTML代码
- 预览HTML: 在页面中预览生成的HTML效果
- 下载JSON: 将JSON数据下载为文件
- 下载HTML: 将HTML代码下载为文件
8.5 技术实现细节
8.5.1 数据获取
- 使用
JSON.parse(JSON.stringify())进行深拷贝,避免引用问题 - 包含完整的组件配置信息和元数据
- 支持画布高度、缩放等状态信息
8.5.2 HTML生成
- 按zIndex排序组件,确保正确的层叠顺序
- 生成完整的CSS样式字符串
- 支持所有组件类型的HTML结构
- 保持组件的绝对定位布局
8.5.3 样式处理
- 合并基础样式和自定义样式
- 生成内联样式字符串
- 支持Ant Design样式类名
- 保持组件的视觉效果
8.6 扩展性
- 支持新增组件类型的HTML生成
- 可自定义HTML模板和样式
- 支持不同的输出格式(Vue组件、React组件等)
- 可扩展为完整的代码生成器
9. 高级扩展
- 支持属性分组、排序、分区等高级配置。
- 支持多类型组件的属性映射与自动渲染。
- 支持国际化、校验、动态属性等。
- 支持画布JSON导出和HTML代码生成。
