Commit be2d3eb792ef8939e96ed01a645678c886dc46e5
1 parent
b2c9bc49
fix: #132 #134
Showing
10 changed files
with
155 additions
and
150 deletions
front-end/h5/src/components/core/editor/edit-panel/background.js
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | * @Author: ly525 |
| 3 | 3 | * @Date: 2019-12-01 18:11:49 |
| 4 | 4 | * @LastEditors : ly525 |
| 5 | - * @LastEditTime : 2019-12-22 18:09:54 | |
| 5 | + * @LastEditTime : 2020-01-15 01:03:31 | |
| 6 | 6 | * @FilePath: /luban-h5/front-end/h5/src/components/core/editor/edit-panel/background.js |
| 7 | 7 | * @Github: https://github.com/ly525/luban-h5 |
| 8 | 8 | * @Description: Do not edit |
| ... | ... | @@ -23,14 +23,11 @@ export default { |
| 23 | 23 | ]) |
| 24 | 24 | }, |
| 25 | 25 | render () { |
| 26 | - return <propsEditPanel layout="vertical" /> | |
| 27 | - }, | |
| 28 | - created () { | |
| 29 | - const bgElement = this.editingPage.elements.find(e => e.name === 'lbp-background') | |
| 30 | - this.setEditingElement(bgElement) | |
| 31 | - }, | |
| 32 | - beforeDestroy () { | |
| 33 | - this.setEditingElement() | |
| 26 | + const bgEle = this.editingPage.elements.find(e => e.name === 'lbp-background') | |
| 27 | + return <propsEditPanel | |
| 28 | + layout="vertical" | |
| 29 | + realEditingElement={bgEle} | |
| 30 | + /> | |
| 34 | 31 | } |
| 35 | 32 | |
| 36 | 33 | } | ... | ... |
front-end/h5/src/components/core/editor/edit-panel/props.js
| 1 | 1 | import Vue from 'vue' |
| 2 | 2 | import { mapState, mapActions } from 'vuex' |
| 3 | -import { getVM } from '../../../../utils/element' | |
| 3 | +import { getVM, getComponentsForPropsEditor } from '../../../../utils/element' | |
| 4 | 4 | |
| 5 | 5 | export default { |
| 6 | 6 | data: () => ({ |
| ... | ... | @@ -10,12 +10,22 @@ export default { |
| 10 | 10 | layout: { |
| 11 | 11 | type: String, |
| 12 | 12 | default: 'horizontal' |
| 13 | + }, | |
| 14 | + // 优先级更高的当前编辑元素 | |
| 15 | + realEditingElement: { | |
| 16 | + type: Object, | |
| 17 | + default: () => null | |
| 13 | 18 | } |
| 14 | 19 | }, |
| 15 | 20 | computed: { |
| 16 | - ...mapState('editor', ['editingElement', 'editingElementEditorConfig']), | |
| 21 | + ...mapState('editor', { | |
| 22 | + stateEditingElement: state => state.editingElement | |
| 23 | + }), | |
| 17 | 24 | customEditorName () { |
| 18 | 25 | return `${this.editingElement.name}-custom-editor` |
| 26 | + }, | |
| 27 | + editingElement () { | |
| 28 | + return this.realEditingElement || this.stateEditingElement | |
| 19 | 29 | } |
| 20 | 30 | }, |
| 21 | 31 | methods: { |
| ... | ... | @@ -42,11 +52,10 @@ export default { |
| 42 | 52 | * 将插件属性的 自定义增强编辑器注入 属性编辑面板中 |
| 43 | 53 | */ |
| 44 | 54 | mixinEnhancedPropsEditor (editingElement) { |
| 45 | - if (!this.editingElementEditorConfig || !this.editingElementEditorConfig.components) return | |
| 46 | - const { components } = this.editingElementEditorConfig | |
| 47 | - for (const key in components) { | |
| 55 | + if (!this.componentsForPropsEditor) return | |
| 56 | + for (const key in this.componentsForPropsEditor) { | |
| 48 | 57 | if (this.$options.components[key]) return |
| 49 | - this.$options.components[key] = components[key] | |
| 58 | + this.$options.components[key] = this.componentsForPropsEditor[key] | |
| 50 | 59 | } |
| 51 | 60 | }, |
| 52 | 61 | /** |
| ... | ... | @@ -81,7 +90,7 @@ export default { |
| 81 | 90 | // editingElement.pluginProps[propKey] = e.target ? e.target.value : e |
| 82 | 91 | // } |
| 83 | 92 | change (e) { |
| 84 | - // TODO fixme: update plugin props in vuex with dispatch | |
| 93 | + // TODO fixme: update plugin props in vuex with dispatch | |
| 85 | 94 | editingElement.pluginProps[propKey] = e.target ? e.target.value : e |
| 86 | 95 | } |
| 87 | 96 | } |
| ... | ... | @@ -140,6 +149,9 @@ export default { |
| 140 | 149 | return this.renderPropsEditorPanel(h, ele) |
| 141 | 150 | }, |
| 142 | 151 | created () { |
| 143 | - window.getEditorApp.$on('setEditingElement', this.loadCustomEditorForPlugin) | |
| 152 | + window.getEditorApp.$on('setEditingElement', (ele) => { | |
| 153 | + this.loadCustomEditorForPlugin() | |
| 154 | + this.componentsForPropsEditor = getComponentsForPropsEditor(ele.name) | |
| 155 | + }) | |
| 144 | 156 | } |
| 145 | 157 | } | ... | ... |
front-end/h5/src/components/core/models/element.js
| ... | ... | @@ -31,42 +31,28 @@ class Element { |
| 31 | 31 | * 3. 为何需要 clone,因为会有 element.clone() 以及 page.clone(), |
| 32 | 32 | * element.pluginProps 和 elementcommonStyle 是引用类型,如果不做 deep_clone 可能会出现意外错误 |
| 33 | 33 | */ |
| 34 | - this.pluginProps = (typeof ele.pluginProps === 'object' && cloneObj({ ...ele.pluginProps, uuid: this.uuid })) || this.getDefaultPluginProps(ele.editorConfig || {}) | |
| 34 | + this.pluginProps = (typeof ele.pluginProps === 'object' && cloneObj({ ...ele.pluginProps, uuid: this.uuid })) || this.getDefaultPluginProps(ele.props || {}) | |
| 35 | 35 | this.commonStyle = (typeof ele.commonStyle === 'object' && cloneObj(ele.commonStyle)) || { ...defaultStyle, zindex: ele.zindex } |
| 36 | 36 | this.events = [] |
| 37 | 37 | this.animations = ele.animations || [] |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | // init prop of plugin |
| 41 | - getDefaultPluginProps (propsConfig) { | |
| 41 | + getDefaultPluginProps (props) { | |
| 42 | 42 | const pluginProps = { |
| 43 | 43 | uuid: this.uuid |
| 44 | 44 | } |
| 45 | - Object.keys(propsConfig).forEach(key => { | |
| 45 | + Object.keys(props).forEach(key => { | |
| 46 | 46 | // #6 |
| 47 | 47 | if (key === 'name') { |
| 48 | 48 | console.warn('Please do not use {name} as plugin prop') |
| 49 | 49 | return |
| 50 | 50 | } |
| 51 | - const defaultValue = propsConfig[key].default | |
| 51 | + const defaultValue = props[key].default | |
| 52 | 52 | pluginProps[key] = typeof defaultValue === 'function' ? defaultValue() : defaultValue |
| 53 | 53 | }) |
| 54 | 54 | return pluginProps |
| 55 | 55 | } |
| 56 | - // getDefaultPluginProps (editorConfig) { | |
| 57 | - // // init prop of plugin | |
| 58 | - // const propConf = editorConfig.propsConfig | |
| 59 | - // const pluginProps = {} | |
| 60 | - // Object.keys(propConf).forEach(key => { | |
| 61 | - // // #6 | |
| 62 | - // if (key === 'name') { | |
| 63 | - // console.warn('Please do not use {name} as plugin prop') | |
| 64 | - // return | |
| 65 | - // } | |
| 66 | - // pluginProps[key] = propConf[key].defaultPropValue | |
| 67 | - // }) | |
| 68 | - // return pluginProps | |
| 69 | - // } | |
| 70 | 56 | |
| 71 | 57 | getStyle ({ position = 'static', isRem = false } = {}) { |
| 72 | 58 | if (this.name === 'lbp-background') { | ... | ... |
front-end/h5/src/components/plugins/lbp-form-button.js
| ... | ... | @@ -75,21 +75,20 @@ export default { |
| 75 | 75 | req.send(formData) |
| 76 | 76 | } |
| 77 | 77 | }, |
| 78 | - editorConfig: { | |
| 79 | - components: { | |
| 80 | - 'lbs-select-input-type': { | |
| 81 | - props: ['value'], | |
| 82 | - computed: { | |
| 83 | - value_: { | |
| 84 | - get () { | |
| 85 | - return this.value | |
| 86 | - }, | |
| 87 | - set (val) { | |
| 88 | - this.$emit('input', val) | |
| 89 | - } | |
| 78 | + componentsForPropsEditor: { | |
| 79 | + 'lbs-select-input-type': { | |
| 80 | + props: ['value'], | |
| 81 | + computed: { | |
| 82 | + value_: { | |
| 83 | + get () { | |
| 84 | + return this.value | |
| 85 | + }, | |
| 86 | + set (val) { | |
| 87 | + this.$emit('input', val) | |
| 90 | 88 | } |
| 91 | - }, | |
| 92 | - template: ` | |
| 89 | + } | |
| 90 | + }, | |
| 91 | + template: ` | |
| 93 | 92 | <a-select v-model="value_" placeholder="类型"> |
| 94 | 93 | <a-option |
| 95 | 94 | v-for="item in options" |
| ... | ... | @@ -99,31 +98,30 @@ export default { |
| 99 | 98 | </a-option> |
| 100 | 99 | </a-select> |
| 101 | 100 | `, |
| 102 | - data: () => ({ | |
| 103 | - options: [ | |
| 104 | - { | |
| 105 | - label: '文字', | |
| 106 | - value: 'text' | |
| 107 | - }, | |
| 108 | - { | |
| 109 | - label: '密码', | |
| 110 | - value: 'password' | |
| 111 | - }, | |
| 112 | - { | |
| 113 | - label: '日期', | |
| 114 | - value: 'date' | |
| 115 | - }, | |
| 116 | - { | |
| 117 | - label: '邮箱', | |
| 118 | - value: 'email' | |
| 119 | - }, | |
| 120 | - { | |
| 121 | - label: '手机号', | |
| 122 | - value: 'tel' | |
| 123 | - } | |
| 124 | - ] | |
| 125 | - }) | |
| 126 | - } | |
| 101 | + data: () => ({ | |
| 102 | + options: [ | |
| 103 | + { | |
| 104 | + label: '文字', | |
| 105 | + value: 'text' | |
| 106 | + }, | |
| 107 | + { | |
| 108 | + label: '密码', | |
| 109 | + value: 'password' | |
| 110 | + }, | |
| 111 | + { | |
| 112 | + label: '日期', | |
| 113 | + value: 'date' | |
| 114 | + }, | |
| 115 | + { | |
| 116 | + label: '邮箱', | |
| 117 | + value: 'email' | |
| 118 | + }, | |
| 119 | + { | |
| 120 | + label: '手机号', | |
| 121 | + value: 'tel' | |
| 122 | + } | |
| 123 | + ] | |
| 124 | + }) | |
| 127 | 125 | } |
| 128 | 126 | } |
| 129 | 127 | } | ... | ... |
front-end/h5/src/components/plugins/lbp-form-input.js
| ... | ... | @@ -54,66 +54,64 @@ export default { |
| 54 | 54 | lineHeight: commonProps.lineHeight, |
| 55 | 55 | textAlign: commonProps.textAlign({ defaultValue: 'left' }) |
| 56 | 56 | }, |
| 57 | - editorConfig: { | |
| 58 | - components: { | |
| 59 | - 'lbs-select-input-type': { | |
| 60 | - props: ['value'], | |
| 61 | - computed: { | |
| 62 | - value_: { | |
| 63 | - get () { | |
| 64 | - return this.value | |
| 65 | - }, | |
| 66 | - set (val) { | |
| 67 | - this.$emit('input', val) | |
| 68 | - } | |
| 57 | + componentsForPropsEditor: { | |
| 58 | + 'lbs-select-input-type': { | |
| 59 | + props: ['value'], | |
| 60 | + computed: { | |
| 61 | + value_: { | |
| 62 | + get () { | |
| 63 | + return this.value | |
| 64 | + }, | |
| 65 | + set (val) { | |
| 66 | + this.$emit('input', val) | |
| 69 | 67 | } |
| 70 | - }, | |
| 71 | - render (h) { | |
| 72 | - return ( | |
| 73 | - <a-select | |
| 74 | - placeholder="类型" | |
| 75 | - value={this.value} | |
| 76 | - onChange={(value) => { | |
| 77 | - this.$emit('input', value) | |
| 78 | - this.$emit('change', value) | |
| 79 | - }} | |
| 80 | - > | |
| 81 | - { | |
| 82 | - this.options.map(option => ( | |
| 83 | - <a-select-option | |
| 84 | - key={option.value} | |
| 85 | - value={option.value} | |
| 86 | - >{option.label}</a-select-option> | |
| 87 | - )) | |
| 88 | - } | |
| 89 | - </a-select> | |
| 90 | - ) | |
| 91 | - }, | |
| 92 | - data: () => ({ | |
| 93 | - options: [ | |
| 94 | - { | |
| 95 | - label: '文字', | |
| 96 | - value: 'text' | |
| 97 | - }, | |
| 98 | - { | |
| 99 | - label: '密码', | |
| 100 | - value: 'password' | |
| 101 | - }, | |
| 102 | - { | |
| 103 | - label: '日期', | |
| 104 | - value: 'date' | |
| 105 | - }, | |
| 68 | + } | |
| 69 | + }, | |
| 70 | + render (h) { | |
| 71 | + return ( | |
| 72 | + <a-select | |
| 73 | + placeholder="类型" | |
| 74 | + value={this.value} | |
| 75 | + onChange={(value) => { | |
| 76 | + this.$emit('input', value) | |
| 77 | + this.$emit('change', value) | |
| 78 | + }} | |
| 79 | + > | |
| 106 | 80 | { |
| 107 | - label: '邮箱', | |
| 108 | - value: 'email' | |
| 109 | - }, | |
| 110 | - { | |
| 111 | - label: '手机号', | |
| 112 | - value: 'tel' | |
| 81 | + this.options.map(option => ( | |
| 82 | + <a-select-option | |
| 83 | + key={option.value} | |
| 84 | + value={option.value} | |
| 85 | + >{option.label}</a-select-option> | |
| 86 | + )) | |
| 113 | 87 | } |
| 114 | - ] | |
| 115 | - }) | |
| 116 | - } | |
| 88 | + </a-select> | |
| 89 | + ) | |
| 90 | + }, | |
| 91 | + data: () => ({ | |
| 92 | + options: [ | |
| 93 | + { | |
| 94 | + label: '文字', | |
| 95 | + value: 'text' | |
| 96 | + }, | |
| 97 | + { | |
| 98 | + label: '密码', | |
| 99 | + value: 'password' | |
| 100 | + }, | |
| 101 | + { | |
| 102 | + label: '日期', | |
| 103 | + value: 'date' | |
| 104 | + }, | |
| 105 | + { | |
| 106 | + label: '邮箱', | |
| 107 | + value: 'email' | |
| 108 | + }, | |
| 109 | + { | |
| 110 | + label: '手机号', | |
| 111 | + value: 'tel' | |
| 112 | + } | |
| 113 | + ] | |
| 114 | + }) | |
| 117 | 115 | } |
| 118 | 116 | } |
| 119 | 117 | } | ... | ... |
front-end/h5/src/components/plugins/lbp-slide.js
front-end/h5/src/components/plugins/lbp-video.js
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | * @Author: ly525 |
| 3 | 3 | * @Date: 2019-12-01 18:11:50 |
| 4 | 4 | * @LastEditors : ly525 |
| 5 | - * @LastEditTime : 2020-01-13 00:31:39 | |
| 5 | + * @LastEditTime : 2020-01-15 00:53:48 | |
| 6 | 6 | * @FilePath: /luban-h5/front-end/h5/src/components/plugins/lbp-video.js |
| 7 | 7 | * @Github: https://github.com/ly525/luban-h5 |
| 8 | 8 | * @Description: Do not edit |
| ... | ... | @@ -96,8 +96,6 @@ export default { |
| 96 | 96 | </div> |
| 97 | 97 | ) |
| 98 | 98 | }, |
| 99 | - editorConfig: { | |
| 100 | - components: { | |
| 101 | - } | |
| 99 | + componentsForPropsEditor: { | |
| 102 | 100 | } |
| 103 | 101 | } | ... | ... |
front-end/h5/src/store/modules/editor.js
front-end/h5/src/store/modules/element.js
| 1 | 1 | import Element from '../../components/core/models/element' |
| 2 | -import { getEditorConfigForEditingElement, swapZindex, getVM } from '../../utils/element' | |
| 2 | +import { swapZindex, getVM } from '../../utils/element' | |
| 3 | 3 | |
| 4 | 4 | // actions |
| 5 | 5 | export const actions = { |
| 6 | 6 | setEditingElement ({ commit }, payload) { |
| 7 | 7 | commit('setEditingElement', payload) |
| 8 | - | |
| 9 | - const vm = (payload && payload.name) ? getEditorConfigForEditingElement(payload.name) : null | |
| 10 | - commit('setEditingElementEditorConfig', vm) | |
| 11 | - | |
| 12 | 8 | payload && window.getEditorApp.$emit('setEditingElement', payload) |
| 13 | 9 | }, |
| 14 | 10 | setElementPosition ({ commit }, payload) { |
| ... | ... | @@ -30,9 +26,6 @@ export const mutations = { |
| 30 | 26 | setEditingElement (state, payload) { |
| 31 | 27 | state.editingElement = payload |
| 32 | 28 | }, |
| 33 | - setEditingElementEditorConfig (state, payload) { | |
| 34 | - state.editingElementEditorConfig = payload | |
| 35 | - }, | |
| 36 | 29 | setElementCommonStyle (state, payload) { |
| 37 | 30 | state.editingElement.commonStyle = { |
| 38 | 31 | ...state.editingElement.commonStyle, |
| ... | ... | @@ -54,7 +47,7 @@ export const mutations = { |
| 54 | 47 | ...value, |
| 55 | 48 | zindex: len + 1 |
| 56 | 49 | } |
| 57 | - const element = new Element({ name, editorConfig: props }) | |
| 50 | + const element = new Element({ name, props }) | |
| 58 | 51 | elements.push(element) |
| 59 | 52 | break |
| 60 | 53 | case 'copy': | ... | ... |
front-end/h5/src/utils/element.js
| ... | ... | @@ -3,10 +3,36 @@ import Vue from 'vue' |
| 3 | 3 | const DESIGN_DRAFT_WIDTH = 320 |
| 4 | 4 | const styleKey = 'commonStyle' |
| 5 | 5 | |
| 6 | -export function getEditorConfigForEditingElement (elementName) { | |
| 6 | +/** | |
| 7 | + * | |
| 8 | + | |
| 9 | + * 获取组件中的 「componentsForPropsEditor」对象 | |
| 10 | + * @param {String} elementName | |
| 11 | + * | |
| 12 | + * 可以查看下面的组件 Demo | |
| 13 | + { | |
| 14 | + name: 'lbp-button', | |
| 15 | + props: { | |
| 16 | + color: { | |
| 17 | + default: 'red', | |
| 18 | + editor: { | |
| 19 | + type: 'custom-color-editor' | |
| 20 | + } | |
| 21 | + } | |
| 22 | + }, | |
| 23 | + componentsForPropsEditor: { | |
| 24 | + 'custom-color-editor': { | |
| 25 | + render() { | |
| 26 | + return <input type="color" /> | |
| 27 | + } | |
| 28 | + } | |
| 29 | + } | |
| 30 | + } | |
| 31 | + */ | |
| 32 | +export function getComponentsForPropsEditor (elementName) { | |
| 7 | 33 | const Ctor = Vue.component(elementName) |
| 8 | 34 | // TODO 为何直接 return new Ctor() 并将其赋值给 vuex 的 state 会报错:Cannot convert a Symbol value to a string |
| 9 | - return new Ctor().$options.editorConfig | |
| 35 | + return new Ctor().$options.componentsForPropsEditor | |
| 10 | 36 | } |
| 11 | 37 | |
| 12 | 38 | export function getVM (pluginName) { | ... | ... |