【低代码编辑器】单个组件(物料)的设计文档

206 阅读4分钟

什么是组件?

组件是编辑器内的最小粒度, 也是编辑器功能实现中最重要的一员。可以把它比喻成一个积木,该积木拥有自己的形状、颜色、大小、合适的位置等。

同理,在网页设计中。一个组件就会拥有自己独特的样式、数据、事件、动画等。当然,它和其他组件也有相同的地方。所以,组件间会存在公用的样式、数据、属性、动画。由此可知,组件的编辑会进行私有和公有的区分。那么你肯定想到了,对于组件来说,同样会以此作为区分。

一、组件的核心属性

由上可知。我们可以将一个组件的属性定义为以下几个部分。

1.数据(data)

组件对外可编辑或可展示的数据。

2.样式(style)

组件对外可编辑或可展示的数据。

3.事件(event)

组件内部事件触发行为 与 组件通信、全局通信事件。

4.动画(animation)

组件动画行为。

二、组件的次要属性

组件本身携带用于逻辑判断、组件维护等属性。

1.版本(version)

组件版本控制。用于组件升级、回退等

2.类型(type)

组件类型区分。唯一值,用于布局、拖拽、组件特殊判断等。

3.布局(layout)

用于限制当前组件的可用布局类型。例如:可用与左右布局、全屏布局

4.可用模块(modules)

每个布局拥有多个模块,该属性用于限制组件,在对应布局下的可用模块有哪些。

三、组件的完整数据

以下是一个组件构成的案例代码。

export default {
  version: '1.0.0', // 版本
  type: WIDGET_SPE_TYPE.LEFT_MENU, // 类型
  layout: [LAYOUT_KEY.LEFT_RIGHT, LAYOUT_KEY.FULL_SCREEN], // 可用布局
  modules: {
    [LAYOUT_KEY.LEFT_RIGHT]: [LEFT_RIGHT_MODULES.LEFT],
    [LAYOUT_KEY.FULL_SCREEN]: [FULL_SCREEN_MODULES.CENTER]
  }, // 可用布局下的可使用模块 布局: 模块
  data: {
    title: '左侧菜单',
    icon: '', // 文章icon
    params: {
      cateKey: '' // 默认空为请求所有
    }, // 文章请求参数 暂时只有type. 使用对象是防止请求参数复杂化后的处理
    jumpUrl: '', // 文章跳转路径。默认会携带当前文章的id与类型
  },
  style: {
    backgroundColor: ''
  },
  event: {
    onMenuClick: {
      bind: [], // 已绑定信息 结构 { id: 'xx', params }
      label: '菜单点击'
    },
    onMenuCollapse: {
      bind: [],
      label: '菜单折叠'
    }
  }
};

四、组件数据、样式、事件的数据编辑

🤔 那么你可能要问了。组件的数据要这么编辑呢?

😃 这你就问对人了。组件的数据编辑与展示我们依赖于JS的特性: 对象引用,当然我们也可以使用object.defineProperty 或者 Proxy。在Vue3版本中。我们使用了ref代理整个数据对象。这也给它绑定上了proxy

所以编辑和展示的我们使用的是同一份数据。对于数据、样式、事件的编辑,我们编辑的就是组件内的data、style、event。

对于以上数据。内部实现了一个通过el-form改造的属性编辑器propertyRender, 以用于属性编辑。

1.propertyRender

该组件主要支持以下几种类型的渲染。

  • Render渲染自定义编辑组件
  • 支持Element-plus所有类型表单组件
  • 支持自定义通用组件
  • 支持错误处理(开发中.....)

所以我们在单个组件文件夹下存在editor.jsx文件。里面设置了Data、Style、Event的配置文件。以下是示例代码。

export const editor = [
  {
    prop: 'title',
    type: ELEMENT_TYPE.INPUT,
    label: '标题'
  },
  {
    prop: 'icon',
    label: '标题图标',
    render: (form) => {
      return (
        <ImgSelector
          v-model={form.icon}
        />
      )
    }
  },
  {
    prop: 'jumpUrl',
    type: ELEMENT_TYPE.INPUT, // 待实现参数绑定
    label: '跳转路径',
    attributes: {
      placeholder: '请输入跳转地址'
    }
  },
  {
    prop: 'params',
    label: '文章列表选择',
    render: (form) => {
      return (
        <ArticleSelector
          v-model={form.params}
        />
      )
    }
  },
];

export const style = [
  {
    prop: 'backgroundColor',
    type: STYLE_TYPE.COLOR_SELECTOR,
    label: '背景颜色'
  },
]

// 事件处理
export const event = [
  {
    prop: 'onMenuClick',
    type: EVENT_TYPE.EVENT_SELECTOR,
    label: '点击事件'
  },
  {
    prop: 'onMenuCollapse',
    type: EVENT_TYPE.EVENT_SELECTOR,
    label: '展开收起'
  }
]

我们可以看到我们在其中使用了多种不同的类型的属性编辑器。 ELEMENT_TYPE.INPUT 是自定义枚举类型

ELEMENT_TYPE.INPUT: Element-plus自带的表单组件

ImgSelector: 组件自定义组件,使用Render渲染

STYLE_TYPE.COLOR_SELECTOREVENT_TYPE.EVENT_SELECTOR: 共用属性编辑组件。

所以我们通过propertyRender就能编辑完成一个组件的所有属性, 不同的区别在于用户如何去正确配置。

五、一个组件的文件结构

组件如何使用?

细心的你一定发现了。前文似乎只介绍了属性结构,组件的编辑原理。但是如何使用并没有提起。不用着急,这会放在编辑器设计文档中进行详细介绍!