一、动态组件核心机制
Vue2动态组件三要素
- component标签:通过is属性动态切换组件
- 组件注册:全局/局部注册可用组件
- 属性传递:v-bind实现动态props
<component
:is="currentComponent"
v-bind="componentProps"
></component>
二、表单设计器实现
1. 表单组件库定义
// src/components/form-items/index.js
export default {
'input-text': {
label: '单行文本',
component: () => import('./TextInput.vue'),
defaultProps: {
placeholder: '请输入内容',
maxlength: 50
}
},
'input-number': {
label: '数字输入',
component: () => import('./NumberInput.vue'),
defaultProps: {
min: 0,
max: 100
}
},
'select': {
label: '下拉选择',
component: () => import('./SelectInput.vue'),
defaultProps: {
options: [
{ label: '选项1', value: 1 },
{ label: '选项2', value: 2 }
]
}
}
}
2. 设计器核心组件
<template>
<div class="designer-container">
<!-- 组件面板 -->
<div class="component-palette">
<div
v-for="(item, type) in componentLib"
:key="type"
class="component-item"
draggable
@dragstart="dragStart(type)"
>
{{ item.label }}
</div>
</div>
<!-- 画布区域 -->
<div
class="designer-canvas"
@drop="handleDrop"
@dragover.prevent
>
<component
v-for="(item, index) in formItems"
:key="item.id"
:is="item.type"
v-bind="item.props"
@config="handleConfig(index)"
/>
</div>
<!-- 属性面板 -->
<props-panel
:currentProps="currentProps"
@update="updateProps"
/>
</div>
</template>
3. 拖拽交互实现
export default {
data() {
return {
formItems: [],
currentProps: null,
activeIndex: null
}
},
methods: {
dragStart(type) {
event.dataTransfer.setData('component-type', type)
},
handleDrop() {
const type = event.dataTransfer.getData('component-type')
this.addComponent(type)
},
addComponent(type) {
const component = this.componentLib[type]
this.formItems.push({
id: Date.now(),
type: type,
props: { ...component.defaultProps }
})
},
handleConfig(index) {
this.activeIndex = index
this.currentProps = this.formItems[index].props
},
updateProps(newProps) {
this.$set(this.formItems[this.activeIndex], 'props', newProps)
}
}
}
三、高级功能扩展
1. 表单JSON导出/导入
// 导出表单配置
exportForm() {
return JSON.stringify(this.formItems.map(item => ({
type: item.type,
props: item.props
}))
}
// 导入表单配置
importForm(json) {
this.formItems = JSON.parse(json).map(item => ({
...item,
id: Date.now()
}))
}
2. 组件联动逻辑
watch: {
'formItems': {
deep: true,
handler(items) {
items.forEach((item, index) => {
if (item.type === 'select' && item.props.options) {
// 当选项变化时更新关联组件
this.$nextTick(() => {
this.updateDependencies(index)
})
}
})
}
}
}
四、实际应用场景
- 问卷调查系统:动态生成问卷表单
- CRM系统:自定义客户字段
- OA审批:可视化流程表单设计
- 数据采集:快速搭建采集页面