一、基于Element Plus自定义扩展字段(以 Steps 步骤条为例)

以下步骤均在 extension 文件夹中进行,新增完成后,Steps控件在 自定义扩展字段 中出现。

1. 定义组件

  1. 配置属性扩展,extension-schema.js中,根据组件属性进行配置

属性说明:
type: 字段组件的类型名称,必须唯一,不能跟已有组件重复;且必须是新建组件的名称,例如组件名为steps-widget.vue,type必须为steps。i18通过type显示容器名称。需要在lang的en-US_extension.js和zh-CN_extension.js的widgetLabel中配置type对应的名称。
category: 容器类型,container容器组件,其他为字段组件。
icon: 容器中显示的图标,可通过iconfont.css进行下载引入展示,也可以直接下载svg图标至 icons/svg 文件夹。
formItemFlag: 是否嵌套el-form-item组件内,默认false。
options: 为组件属性,配置属性后可在组件类中通过field.options.xxxx进行绑定

示例:
// extension/sample/extension-schema.js
(1) 配置属性扩展
export const stepsSchema = {
	type: 'steps',
	icon: 'steps',
	formItemFlag: true,
	options: {
		name: '',
		space: '',
		direction: 'horizontal',
		acive: 0,
		alignCenter: false,
		simple: false,
		optionsItem: [
  			{ label: 'Step 1', value: 1},
  			{ label: 'Step 2', value: 2},
  			{ label: 'Step 3', value: 3},
		]
	}
}
(2)引入图标,下载svg图标至icons/svg文件夹中,名称同stepsSchema.icon一致。
(3) 配置国际化语言
// zh-CN.js
designer: {
	...
	steps: '步骤条',
}

// en-US.js
designer: {
	...
	steps: 'Steps'
}

// zh-CN_extension.js
setting: {
	...
	stepSpace: '间距',
  	stepDirection: '显示方向',
  	stepActive: '当前激活步骤',
  	stepAlignCenter: '是否进行居中对齐',
  	stepSimple: '是否应用简洁风格'
}
// en_US_extension.js
setting: {
	...
	stepSpace: 'Space',
  	stepDirection: 'Direction',
  	stepActive: 'Active',
  	stepAlignCenter: 'Align Center',
  	stepSimple: 'Simple'
}
  1. 编写组件的SFC文件
  • 字段组件: 字段组件在设计期和运行期共用,故只需要编写一个SFC文件即可(参照alert-widget书写字段组件代码)。
samples 文件夹中新建组件,命名规则需严格遵守:组件名称-widget,因为之后的拖拽加载是通过component的:is=“{{type}}-widget”。

像elementui那样在封装的组件中添加其他组件 element组件扩展_vue.js

  • 容器组件: 容器组件有两种状态——设计期和运行期,故需要注册两个组件(参照card文件夹书写容器组件代码)。
samples 文件夹中新建组件,设计期的容器组件需严格遵守命名规则:组件名称-widget;运行期的容器组件则没有要求。

像elementui那样在封装的组件中添加其他组件 element组件扩展_字段_02

示例:
// 以字段组件 Steps 为例
// steps-widget.vue
	<template>
		<static-content-wrapper :designer="designer" :field="field" :design-state="designState"
                      :parent-widget="parentWidget" :parent-list="parentList" :index-of-parent-list="indexOfParentList"
                      :sub-form-row-index="subFormRowIndex" :sub-form-col-index="subFormColIndex" :sub-form-row-id="subFormRowId">
			<el-steps :active="field.options.active" :align-center="field.options.alignCenter" :space="field.options.space" :direction="field.options.direction" :simple="field.options.simple">
    			<el-step v-for="item in field.options.optionsItem" :key="item.value" :title="item.label" />
			</el-steps>
		</static-content-wrapper>
	</template>

2. 引入组件,并加载属性编译器extension-loader.js

  1. 加载字段组件步骤
(1)引入组件属性扩展
import {stepsSchema} from "@/extension/samples/extension-schema"
(2)引入组件
import stepsWidget from '@/extension/samples/steps/steps-widget'
(3)引入SFC配置(在‘6’中说明SFC代码配置)
import {StepsTemplateGenerator} from '@/extension/samples/extension-sfc-generator'
(4)加载属性扩展
addCustomWidgetSchema(stepsSchema)  //加载组件Json Schema
(5)注册组件
app.component(stepsWidget.name, stepsWidget)
(6)注册主页面右侧属性配置器
let directionOptions = [
	{label: 'horizontal', value: 'horizontal'},
	{label: 'vertical', value: 'vertical'},
]
PERegister.registerCPEditor(app, 'steps-direction', 'steps-direction-editor',
	PEFactory.createSelectEditor('direction', 'extension.setting.stepDirection',
	{optionItems: directionOptions}))
	
PERegister.registerCPEditor(app, 'steps-space', 'steps-space-editor',
	PEFactory.createInputTextEditor('space', 'extension.setting.stepSpace'))

PERegister.registerCPEditor(app, 'steps-active', 'steps-active-editor',
	PEFactory.createInputNumberEditor('active', 'extension.setting.stepActive'))

PERegister.registerCPEditor(app, 'steps-alignCenter', 'steps-alignCenter-editor',
	PEFactory.createBooleanEditor('alignCenter', 'extension.setting.stepAlignCenter'))

PERegister.registerCPEditor(app, 'steps-simple', 'steps-simple-editor',
	PEFactory.createBooleanEditor('simple', 'extension.setting.stepSimple'))
(7)注册SFC代码生成器
registerFWGenerator('steps', stepsTemplateGenerator)
示例

像elementui那样在封装的组件中添加其他组件 element组件扩展_vue.js_03

  1. 加载容器组件步骤

3. 编辑SFC代码生成器

// extension-sfc-generator.js
export const stepsTemplateGenerator = (fw, formConfig) => {
  const wop = fw.options
  const attrArr = Object.keys(wop).filter(item => !['name', 'optionsItem'].includes(item));
  let attrStr = attrArr.reduce(function(prev, cur, index, arr) {
    let str =  ` :${cur}="${wop[cur]}"`
    return prev + str;
  })

  const stepOptions = buildStepChildren(fw, formConfig)


  return `<el-steps ${attrStr}>${stepOptions}</el-steps>`
}

const buildStepChildren = (fw, formConfig) => {
  let wop = fw.options
  return `<el-step v-for="(item, index) in ${wop.name}Options" :key="index" :title="item.label" />`
}
示例

像elementui那样在封装的组件中添加其他组件 element组件扩展_前端_04

二、基于其他框架自定义扩展字段(vant篇)

三、自定义开发字段