Skip to content

组件中获取设计器

在自定义组件中,可以通过 Vue 依赖注入机制获取设计器实例,从而实现对表单设计器的编程式访问和控制。这个功能让您能够创建与设计器深度集成的自定义组件。

设计器实例的完整数据结构和可用方法请查阅帮助文档

基本用法

注入设计器实例

在自定义组件中,通过 inject 选项声明需要注入的设计器实例:

vue
<template>
    <input type="text" v-model="title" @change="onChange">
</template>
<script>
    import {defineComponent} from 'vue';
    export default defineComponent({
        name: 'FieldInput',
        // 关键步骤:声明需要注入的设计器实例
        // Vue会自动从父组件中查找并提供designer实例
        inject: ['designer'],
        data() {
            return {
                title: ''
            }
        },
        computed: {
            activeRule() {
                return this.designer.setupState.activeRule;
                //return this.designer.activeRule; (vue2)
            }
        },
        methods: {
            onChange() {
                //直接修改当前选中的规则
                this.activeRule.title = this.title;
            }
        }
    });
</script>

设计器实例结构

主要属性

设计器实例提供了丰富的属性和方法,主要包括:

  • setupState: 设计器的响应式状态
    • activeRule: 当前选中的规则对象
    • t: 国际化翻译函数
    • formOptions: 表单配置选项
    • dragForm: 拖拽表单实例

访问当前规则

vue
<script>
export default defineComponent({
    inject: ['designer'],
    computed: {
        // 获取当前选中的规则
        activeRule() {
            return this.designer.setupState.activeRule;
        },
        // 获取表单配置
        formOptions() {
            return this.designer.setupState.formOptions;
        },
        // 获取翻译函数
        t() {
            return this.designer.setupState.t;
        }
    }
});
</script>

实际应用示例

1. 样式配置组件

参考 CssInput.vue 组件的实现,展示如何创建样式配置功能:

vue
<template>
    <div class="css-input">
        <el-badge type="warning" is-dot :hidden="!configured">
            <div class="css-btn" @click="visible = true">
                <i class="fc-icon icon-stack"></i>
                级联样式
            </div>
        </el-badge>
        <el-dialog v-model="visible" title="级联样式配置">
            <StyleEditor v-model="cssValue" />
            <template #footer>
                <el-button @click="visible = false">取消</el-button>
                <el-button type="primary" @click="onOk">确定</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script>
export default defineComponent({
    name: 'CssInput',
    inject: ['designer'],
    computed: {
        activeRule() {
            return this.designer.setupState.activeRule;
        },
        configured() {
            return !is.empty(this.activeRule?.$css);
        }
    },
    data() {
        return {
            visible: false,
            cssValue: ''
        };
    },
    methods: {
        onOk() {
            // 直接修改当前规则的样式
            this.activeRule.$css = this.cssValue.trim();
            this.visible = false;
        }
    }
});
</script>

2. 规则属性编辑器

创建一个用于编辑规则属性的组件:

vue
<template>
    <div class="rule-editor">
        <el-form :model="formData" label-width="80px">
            <el-form-item label="字段名">
                <el-input v-model="formData.field" @change="updateRule" />
            </el-form-item>
            <el-form-item label="标题">
                <el-input v-model="formData.title" @change="updateRule" />
            </el-form-item>
            <el-form-item label="是否必填">
                <el-switch v-model="formData.required" @change="updateRule" />
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
export default defineComponent({
    name: 'RuleEditor',
    inject: ['designer'],
    computed: {
        activeRule() {
            return this.designer.setupState.activeRule;
        }
    },
    data() {
        return {
            formData: {
                field: '',
                title: '',
                required: false
            }
        };
    },
    watch: {
        activeRule: {
            handler(rule) {
                if (rule) {
                    this.formData = {
                        field: rule.field || '',
                        title: rule.title || '',
                        required: rule.$required || false
                    };
                }
            },
            immediate: true
        }
    },
    methods: {
        updateRule() {
            if (this.activeRule) {
                // 更新规则属性
                this.activeRule.field = this.formData.field;
                this.activeRule.title = this.formData.title;
                this.activeRule.$required = this.formData.required;
            }
        }
    }
});
</script>

3. 表单配置组件

创建一个用于配置表单全局选项的组件:

vue
<template>
    <div class="form-config">
        <el-form :model="config" label-width="100px">
            <el-form-item label="标签位置">
                <el-select v-model="config.labelPosition" @change="updateFormOptions">
                    <el-option label="右对齐" value="right" />
                    <el-option label="左对齐" value="left" />
                    <el-option label="顶部对齐" value="top" />
                </el-select>
            </el-form-item>
            <el-form-item label="表单尺寸">
                <el-select v-model="config.size" @change="updateFormOptions">
                    <el-option label="大" value="large" />
                    <el-option label="默认" value="default" />
                    <el-option label="小" value="small" />
                </el-select>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
export default defineComponent({
    name: 'FormConfig',
    inject: ['designer'],
    computed: {
        formOptions() {
            return this.designer.setupState.formOptions;
        }
    },
    data() {
        return {
            config: {
                labelPosition: 'right',
                size: 'default'
            }
        };
    },
    watch: {
        formOptions: {
            handler(options) {
                if (options.form) {
                    this.config = {
                        labelPosition: options.form.labelPosition || 'right',
                        size: options.form.size || 'default'
                    };
                }
            },
            immediate: true
        }
    },
    methods: {
        updateFormOptions() {
            // 更新表单配置
            this.designer.setupState.formOptions.form = {
                ...this.designer.setupState.formOptions.form,
                ...this.config
            };
        }
    }
});
</script>

注意事项

  1. Vue 版本兼容性:

    • Vue 3: 使用 this.designer.setupState.activeRule
    • Vue 2: 使用 this.designer.activeRule
  2. 响应式更新: 设计器实例是响应式的,修改 activeRule 的属性会自动更新设计器界面

  3. 生命周期: 确保在组件挂载后再访问设计器实例,避免获取到 undefined

  4. 错误处理: 在访问设计器属性前,建议先检查实例是否存在

vue
<script>
export default defineComponent({
    inject: ['designer'],
    computed: {
        activeRule() {
            return this.designer?.setupState?.activeRule;
        }
    },
    methods: {
        safeUpdateRule() {
            if (this.activeRule) {
                this.activeRule.title = '新标题';
            }
        }
    }
});
</script>

通过掌握设计器实例的获取和使用,您将能够创建出功能强大的自定义组件,深度集成到表单设计器中,为用户提供更丰富的交互体验。