How to Implement Custom Editor Panels for Plugin Properties in Luban H5
Set custom: true in your plugin definition and provide a lazy-loaded Vue component via the editor field to replace the generic right-panel form with a specialized property interface.
Luban H5 is an open-source visual page builder that relies on a plugin-based architecture for its components. While the default right-panel UI handles standard property editing, complex plugins often require specialized interfaces for rich configuration. This guide explains how to implement custom editor panels for plugin properties in Luban H5 by leveraging the custom flag, lazy-loaded editor components, and the core rendering logic in props.js.
How Luban H5 Discovers Custom Editors
The editor follows a four-step resolution process to determine whether to render a generic form or a custom Vue component.
Plugin Registration with the custom Flag
In the plugin's main entry file, setting custom: true signals to the core that this component provides its own property editor. The editor property points to a Vue component that the core loads lazily.
In front-end/h5/src/components/core/plugins/lbp-slide.js, you can see this pattern in production plugins.
Right-Panel Rendering Logic
The file front-end/h5/src/components/core/editor/right-panel/props.js contains the logic that reads the plugin's prop schema. When it encounters custom: true at the plugin level, it imports and renders the component specified in the editor field instead of the default form generator.
Prop-Level Customization
Individual properties within the schema can also declare custom: true. This allows fine-grained control where specific fields use dedicated sub-editors (such as color pickers or table editors) while other fields remain generic.
Required Files and Project Structure
To implement a custom editor panel, you will create or modify the following files:
| File Path | Purpose | Required Changes |
|---|---|---|
front-end/h5/src/components/core/plugins/<your-plugin>.js |
Plugin registration and schema definition | Add custom: true and editor: () => import('./editor.vue') |
front-end/h5/src/components/core/plugins/<your-plugin>/editor.vue |
Custom property panel UI | Implement the Vue component using Luban UI primitives like LbFormItem and LbInput |
front-end/h5/src/components/core/editor/right-panel/props.js |
Core rendering logic | No changes required unless extending the loader |
Step-by-Step Implementation
Step 1: Create the Plugin Entry
Define your plugin with the custom flag and lazy-loaded editor path.
// front-end/h5/src/components/core/plugins/my-plugin.js
import MyComponent from './MyComponent.vue'
export default {
name: 'my-plugin',
component: MyComponent,
// ★ Tell Luban to use a custom property editor
custom: true,
// Path to the editor UI (lazy‑loaded)
editor: () => import('./editor.vue'),
// Example of a prop that also uses a custom sub‑editor
props: {
items: {
type: Array,
default: () => [],
// Each item will be edited by a dedicated sub‑editor
custom: true
}
}
}
Step 2: Build the Custom Editor Component
Create the Vue component that renders in the right panel. Use Luban's UI primitives and Vuex helpers to bind data.
<template>
<div class="my-plugin-editor">
<lb-form-item :label="$t('items')">
<lb-button type="primary" @click="addItem">
{{ $t('addItem') }}
</lb-button>
</lb-form-item>
<div v-for="(item, i) in value.items" :key="i" class="item-row">
<lb-input v-model="item.text" :placeholder="$t('itemText')" />
<lb-button @click="removeItem(i)">{{ $t('remove') }}</lb-button>
</div>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'MyPluginEditor',
computed: {
// `editingElement` is the element currently selected in the canvas
...mapState('editor', ['editingElement']),
// Shortcut to plugin‑specific data
value() {
return this.editingElement
}
},
methods: {
...mapMutations('editor', ['updateEditingElement']),
addItem() {
const items = [...this.value.items, { text: '' }]
this.updateEditingElement({ items })
},
removeItem(idx) {
const items = this.value.items.filter((_, i) => i !== idx)
this.updateEditingElement({ items })
}
}
}
</script>
<style scoped>
.item-row {
display: flex;
align-items: center;
margin-top: 8px;
}
</style>
Key Source Files Reference
Understanding the core implementation helps debug custom editors. These files handle the detection and rendering logic:
front-end/h5/src/components/core/editor/right-panel/props.js– Core logic that inspects the plugin schema and renders either the generic form or the customeditorcomponent.front-end/h5/src/components/core/plugins/lbp-slide.js– Production example demonstrating thecustom: trueflag.docs/zh/plugin-development/how-it-works/custom-editor-single-prop.md– Documentation for single-property custom editors.docs/zh/plugin-development/how-it-works/custom-editor-multiple-props.md– Documentation for multi-property custom editors.
Best Practices and Performance Tips
When building custom editor panels for Luban H5 plugins, follow these guidelines to ensure maintainability and performance:
- Use lazy loading – Always define the
editorproperty as a function returning a dynamic import:editor: () => import('./editor.vue'). The core system invokes this function only when the user selects your plugin, keeping the initial application bundle small. - Bind to Vuex correctly – Access the selected element via
mapState('editor', ['editingElement'])and commit changes throughmapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data. - Scope your styles – Always add
scopedto the<style>tag ineditor.vueto prevent CSS leaks into the canvas or other editor panels. - Leverage Luban UI primitives – Use
LbFormItem,LbInput,LbButton, andLbSelectinstead of raw HTML elements to maintain visual consistency with the rest of the builder. - Internationalize labels – Use
$t('key')for all user-facing strings, adding keys tosrc/locales/lang/*.jsto support multiple languages.
Summary
To implement custom editor panels for plugin properties in Luban H5:
- Set
custom: truein your plugin definition to signal the core to bypass the generic form. - Provide an
editorfunction that lazy-loads your Vue component (e.g.,editor: () => import('./editor.vue')). - Build the editor component using Luban UI primitives and Vuex helpers (
mapState,mapMutations) to bind to the selected canvas element. - Optionally mark individual
propswithcustom: truefor fine-grained control over specific fields.
The core logic in front-end/h5/src/components/core/editor/right-panel/props.js handles the rest, automatically swapping the default panel for your custom implementation whenever users select your plugin on the canvas.
Frequently Asked Questions
How does Luban H5 decide when to show a custom editor versus the default property form?
The right-panel controller in front-end/h5/src/components/core/editor/right-panel/props.js inspects the selected plugin's schema. If the plugin object contains custom: true, the core imports the component specified in the editor field and renders it instead of iterating through the generic prop schema. If custom is falsy or omitted, the system falls back to the standard form generator.
Can I use a custom editor for just one specific property while keeping the rest generic?
Yes. You can mark individual properties with custom: true inside the props definition. When the generic form generator encounters a prop with this flag, it looks for a dedicated editor component for that specific field while rendering standard inputs for all other properties. This hybrid approach allows you to build specialized interfaces for complex fields without reimplementing the entire panel.
What is the recommended way to handle state synchronization between the custom editor and the canvas?
Always use the Vuex store module editor provided by Luban H5. Access the currently selected element via mapState('editor', ['editingElement']) and commit changes using mapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data. Directly mutating the element object without the mutation may cause reactivity issues or break undo/redo functionality.
Does implementing a custom editor affect the initial bundle size of the Luban H5 builder?
No, provided you use lazy loading. Define the editor property as a function returning a dynamic import: editor: () => import('./editor.vue'). The core system invokes this function only when the user selects your plugin, causing the custom editor code to be fetched on demand. This keeps the initial application bundle small and improves startup performance for the page builder.```markdown
Set custom: true in your plugin definition and provide a Vue component via the editor field to replace the generic right-panel form with a specialized property interface.
Luban H5 is an open-source visual page builder that relies on a plugin-based architecture for its components. While the default right-panel UI handles basic property editing, complex plugins often require specialized interfaces for rich configuration. This guide explains how to implement custom editor panels for plugin properties in Luban H5 by leveraging the custom flag, lazy-loaded editor components, and the core rendering logic in props.js.
How Luban H5 Discovers Custom Editors
The editor follows a four-step resolution process to determine whether to render a generic form or a custom Vue component.
Plugin Registration with the custom Flag
In the plugin's main entry file, setting custom: true signals to the core that this component provides its own property editor. The editor property points to a Vue component that the core loads lazily.
In front-end/h5/src/components/core/plugins/lbp-slide.js, you can see this pattern in production plugins.
Right-Panel Rendering Logic
The file front-end/h5/src/components/core/editor/right-panel/props.js contains the logic that reads the plugin's prop schema. When it encounters custom: true at the plugin level, it imports and renders the component specified in the editor field instead of the default form generator.
Prop-Level Customization
Individual properties within the schema can also declare custom: true. This allows fine-grained control where specific fields use dedicated sub-editors (such as color pickers or table editors) while other fields remain generic.
Required Files and Project Structure
To implement a custom editor panel, you will create or modify the following files:
| File Path | Purpose | Required Changes |
|---|---|---|
front-end/h5/src/components/core/plugins/<your-plugin>.js |
Plugin registration and schema definition | Add custom: true and editor: () => import('./editor.vue') |
front-end/h5/src/components/core/plugins/<your-plugin>/editor.vue |
Custom property panel UI | Implement the Vue component using Luban UI primitives like LbFormItem and LbInput |
front-end/h5/src/components/core/editor/right-panel/props.js |
Core rendering logic | No changes required unless extending the loader |
Step-by-Step Implementation
Step 1: Create the Plugin Entry
Define your plugin with the custom flag and lazy-loaded editor path.
// front-end/h5/src/components/core/plugins/my-plugin.js
import MyComponent from './MyComponent.vue'
export default {
name: 'my-plugin',
component: MyComponent,
// ★ Tell Luban to use a custom property editor
custom: true,
// Path to the editor UI (lazy‑loaded)
editor: () => import('./editor.vue'),
// Example of a prop that also uses a custom sub‑editor
props: {
items: {
type: Array,
default: () => [],
// Each item will be edited by a dedicated sub‑editor
custom: true
}
}
}
Step 2: Build the Custom Editor Component
Create the Vue component that renders in the right panel. Use Luban's UI primitives and Vuex helpers to bind data.
<template>
<div class="my-plugin-editor">
<lb-form-item :label="$t('items')">
<lb-button type="primary" @click="addItem">
{{ $t('addItem') }}
</lb-button>
</lb-form-item>
<div v-for="(item, i) in value.items" :key="i" class="item-row">
<lb-input v-model="item.text" :placeholder="$t('itemText')" />
<lb-button @click="removeItem(i)">{{ $t('remove') }}</lb-button>
</div>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'MyPluginEditor',
computed: {
// `editingElement` is the element currently selected in the canvas
...mapState('editor', ['editingElement']),
// Shortcut to plugin‑specific data
value() {
return this.editingElement
}
},
methods: {
...mapMutations('editor', ['updateEditingElement']),
addItem() {
const items = [...this.value.items, { text: '' }]
this.updateEditingElement({ items })
},
removeItem(idx) {
const items = this.value.items.filter((_, i) => i !== idx)
this.updateEditingElement({ items })
}
}
}
</script>
<style scoped>
.item-row {
display: flex;
align-items: center;
margin-top: 8px;
}
</style>
Key Source Files Reference
Understanding the core implementation helps debug custom editors. These files handle the detection and rendering logic:
front-end/h5/src/components/core/editor/right-panel/props.js– Core logic that inspects the plugin schema and renders either the generic form or the customeditorcomponent.front-end/h5/src/components/core/plugins/lbp-slide.js– Production example demonstrating thecustom: trueflag.docs/zh/plugin-development/how-it-works/custom-editor-single-prop.md– Documentation for single-property custom editors.docs/zh/plugin-development/how-it-works/custom-editor-multiple-props.md– Documentation for multi-property custom editors.
Best Practices and Performance Tips
When building custom editor panels for Luban H5 plugins, follow these guidelines to ensure maintainability and performance:
- Use lazy loading – Always define the
editorproperty as a function returning a dynamic import:editor: () => import('./editor.vue'). This prevents the custom editor code from bloating the initial bundle. - Bind to Vuex correctly – Access the selected element via
mapState('editor', ['editingElement'])and commit changes usingmapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data. - Scope your styles – Always add
scopedto the<style>tag ineditor.vueto prevent CSS leaks into the canvas. - Leverage Luban UI primitives – Use
LbFormItem,LbInput,LbButton, andLbSelectinstead of raw HTML elements to maintain visual consistency with the rest of the builder. - Internationalize labels – Use
$t('key')for all user-facing strings, adding keys tosrc/locales/lang/*.jsto support multiple languages.
Summary
To implement custom editor panels for plugin properties in Luban H5:
- Set
custom: truein your plugin definition to signal the core to bypass the generic form. - Provide an
editorfunction that lazy-loads your Vue component (e.g.,editor: () => import('./editor.vue')). - Build the editor component using Luban UI primitives and Vuex helpers (
mapState,mapMutations) to bind to the selected canvas element. - Optionally mark individual
propswithcustom: truefor fine-grained control over specific fields.
The core logic in front-end/h5/src/components/core/editor/right-panel/props.js handles the rest, automatically swapping the default panel for your custom implementation whenever users select your plugin on the canvas.
Frequently Asked Questions
How does Luban H5 decide when to show a custom editor versus the default property form?
The right-panel controller in front-end/h5/src/components/core/editor/right-panel/props.js inspects the selected plugin's schema. If the plugin object contains custom: true, the core imports the component specified in the editor field and renders it instead of iterating through the generic prop schema. If custom is falsy or omitted, the system falls back to the standard form generator.
Can I use a custom editor for just one specific property while keeping the rest generic?
Yes. You can mark individual properties with custom: true inside the props definition. When the generic form generator encounters a prop with this flag, it looks for a dedicated editor component for that specific field while rendering standard inputs for all other properties. This hybrid approach allows you to build specialized interfaces for complex fields without reimplementing the entire panel.
What is the recommended way to handle state synchronization between the custom editor and the canvas?
Always use the Vuex store module editor provided by Luban H5. Access the currently selected element via mapState('editor', ['editingElement']) and commit changes using mapMutations('editor', ['updateEditingElement']). This ensures that modifications in your custom right-panel are immediately reflected on the canvas and persisted with the project data. Directly mutating the element object without the mutation may cause reactivity issues or break undo/redo functionality.
Does implementing a custom editor affect the initial bundle size of the Luban H5 builder?
No, provided you use lazy loading. Define the editor property as a function returning a dynamic import: editor: () => import('./editor.vue'). The core system invokes this function only when the user selects your plugin, causing the custom editor code to be fetched on demand. This keeps the initial application bundle small and improves startup performance for the page builder.```
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →