Commit d04cf043b7558729a15123456fbc2a0025f08c3e

Authored by ly525
1 parent 714b898c

chore(editor): #2 edit plugin props in the props editor panel

Showing 1 changed file with 104 additions and 82 deletions
front-end/h5/src/views/Editor.vue
@@ -84,14 +84,12 @@ const LbpButton = { @@ -84,14 +84,12 @@ const LbpButton = {
84 } 84 }
85 }, 85 },
86 editorConfig: { 86 editorConfig: {
87 - propConfig: {  
88 - name: { 87 + propsConfig: {
  88 + text: {
89 type: 'el-input', 89 type: 'el-input',
90 label: '按钮文字', 90 label: '按钮文字',
91 require: true, 91 require: true,
92 - widgetProps: {  
93 - value: '按钮'  
94 - } 92 + defaultPropValue: '按钮'
95 }, 93 },
96 fontSize: { 94 fontSize: {
97 type: 'el-input-number', 95 type: 'el-input-number',
@@ -102,10 +100,7 @@ const LbpButton = { @@ -102,10 +100,7 @@ const LbpButton = {
102 min: 12, 100 min: 12,
103 max: 144 101 max: 144
104 }, 102 },
105 - widgetProps: {  
106 - value: 14  
107 -  
108 - } 103 + defaultPropValue: 14
109 }, 104 },
110 color: { 105 color: {
111 type: 'el-input', 106 type: 'el-input',
@@ -115,9 +110,7 @@ const LbpButton = { @@ -115,9 +110,7 @@ const LbpButton = {
115 type: 'color' 110 type: 'color'
116 }, 111 },
117 require: true, 112 require: true,
118 - widgetProps: {  
119 - value: ''  
120 - } 113 + defaultPropValue: 'black'
121 }, 114 },
122 backgroundColor: { 115 backgroundColor: {
123 type: 'el-input', // lbs-color-picker 116 type: 'el-input', // lbs-color-picker
@@ -126,9 +119,7 @@ const LbpButton = { @@ -126,9 +119,7 @@ const LbpButton = {
126 type: 'color' 119 type: 'color'
127 }, 120 },
128 require: true, 121 require: true,
129 - widgetProps: {  
130 - value: ''  
131 - } 122 + defaultPropValue: '#ffffff' // TODO why logogram for color does't work?
132 }, 123 },
133 borderColor: { 124 borderColor: {
134 type: 'el-input', // lbs-color-picker 125 type: 'el-input', // lbs-color-picker
@@ -137,9 +128,7 @@ const LbpButton = { @@ -137,9 +128,7 @@ const LbpButton = {
137 type: 'color' 128 type: 'color'
138 }, 129 },
139 require: true, 130 require: true,
140 - widgetProps: {  
141 - value: '#ced4da'  
142 - } 131 + defaultPropValue: '#eeeeee'
143 }, 132 },
144 borderWidth: { 133 borderWidth: {
145 type: 'el-input-number', 134 type: 'el-input-number',
@@ -150,9 +139,7 @@ const LbpButton = { @@ -150,9 +139,7 @@ const LbpButton = {
150 min: 1, 139 min: 1,
151 max: 10 140 max: 10
152 }, 141 },
153 - widgetProps: {  
154 - value: 1  
155 - } 142 + defaultPropValue: 1
156 }, 143 },
157 borderRadius: { 144 borderRadius: {
158 type: 'el-input-number', 145 type: 'el-input-number',
@@ -163,10 +150,7 @@ const LbpButton = { @@ -163,10 +150,7 @@ const LbpButton = {
163 min: 0, 150 min: 0,
164 max: 10 151 max: 10
165 }, 152 },
166 - widgetProps: {  
167 - value: 0  
168 -  
169 - } 153 + defaultPropValue: 0
170 }, 154 },
171 lineHeight: { 155 lineHeight: {
172 type: 'el-input-number', 156 type: 'el-input-number',
@@ -177,19 +161,13 @@ const LbpButton = { @@ -177,19 +161,13 @@ const LbpButton = {
177 min: 0.1, 161 min: 0.1,
178 max: 10 162 max: 10
179 }, 163 },
180 - widgetProps: {  
181 - value: 1  
182 -  
183 - } 164 + defaultPropValue: 1
184 }, 165 },
185 textAlign: { 166 textAlign: {
186 type: 'lbs-text-align', 167 type: 'lbs-text-align',
187 label: '文字对齐', 168 label: '文字对齐',
188 require: true, 169 require: true,
189 - widgetProps: {  
190 - value: 'center'  
191 -  
192 - } 170 + defaultPropValue: 'center'
193 } 171 }
194 }, 172 },
195 components: { 173 components: {
@@ -293,21 +271,51 @@ const PluginList = [ @@ -293,21 +271,51 @@ const PluginList = [
293 } 271 }
294 ] 272 ]
295 273
  274 +const defaultProps = {
  275 + top: 100,
  276 + left: 100,
  277 + width: 100,
  278 + height: 40,
  279 + zindex: 1,
  280 + textAlign: 'center',
  281 + color: '#000000',
  282 + backgroundColor: '#ffffff',
  283 + fontSize: 14
  284 +}
  285 +
296 class Element { 286 class Element {
297 constructor (ele) { 287 constructor (ele) {
298 - const { defaultPropsValue = {} } = ele  
299 - this.type = ele.name 288 + // TODO 需要处理plugin的prop中是 name 的,会覆盖 this.name,
  289 + // 或者将plugin的props赋值给this.pluginProps,这样可以避免冲突,也可以知道哪些是plugin 的props
300 this.name = ele.name 290 this.name = ele.name
301 - this.zindex = ele.zindex || defaultPropsValue.zindex || 1  
302 - this.style = {  
303 - top: ele.top || defaultPropsValue.top || 100,  
304 - left: ele.left || defaultPropsValue.left || 100,  
305 - ...defaultPropsValue  
306 - } 291 + this.editorConfig = ele.editorConfig || {}
  292 + this.init()
307 } 293 }
308 294
309 - getStyle () { 295 + init () {
  296 + // init common props
  297 + Object.keys(defaultProps).forEach(key => {
  298 + this[key] = defaultProps[key]
  299 + })
  300 +
  301 + // init prop of plugin
  302 + const propConf = this.editorConfig.propsConfig
  303 + Object.keys(propConf).forEach(key => {
  304 + this[key] = propConf[key].defaultPropValue
  305 + })
  306 + }
310 307
  308 + getStyle () {
  309 + return {
  310 + top: `${this.top}px`,
  311 + left: `${this.left}px`,
  312 + width: `${this.width}px`,
  313 + height: `${this.height}px`,
  314 + fontSize: `${this.fontSize}px`,
  315 + color: this.color,
  316 + backgroundColor: this.backgroundColor,
  317 + textAlign: this.textAlign
  318 + }
311 } 319 }
312 320
313 getClass () { 321 getClass () {
@@ -322,27 +330,29 @@ class Element { @@ -322,27 +330,29 @@ class Element {
322 const Editor = { 330 const Editor = {
323 name: 'Editor', 331 name: 'Editor',
324 components: { 332 components: {
325 - EditorPanel: {  
326 - template: '<div>Editor Panel</div>'  
327 - }  
328 }, 333 },
329 data: () => ({ 334 data: () => ({
330 pages: [], 335 pages: [],
331 - elements: [] 336 + elements: [],
  337 + editingElement: null
332 }), 338 }),
333 methods: { 339 methods: {
  340 + getEditorConfig (pluginName) {
  341 + return this.$options.components[pluginName].editorConfig
  342 + },
334 /** 343 /**
335 * !#zh 点击插件,copy 其基础数据到组件树(中间画布) 344 * !#zh 点击插件,copy 其基础数据到组件树(中间画布)
336 * pluginInfo {Object}: 插件列表中的基础数据, {name}=pluginInfo 345 * pluginInfo {Object}: 插件列表中的基础数据, {name}=pluginInfo
337 */ 346 */
338 clone ({ name }) { 347 clone ({ name }) {
  348 + debugger
339 const zindex = this.elements.length + 1 349 const zindex = this.elements.length + 1
340 - const defaultPropsValue = this.getPropsDefaultValue(name)  
341 - this.elements.push(new Element({ name, zindex, defaultPropsValue }))  
342 - // return new Element({ name, zindex }) 350 + // const defaultPropsValue = this.getPropsDefaultValue(name)
  351 + const editorConfig = this.getEditorConfig(name)
  352 + this.elements.push(new Element({ name, zindex, editorConfig }))
343 }, 353 },
344 setCurrentEditingElement (element) { 354 setCurrentEditingElement (element) {
345 - 355 + this.editingElement = element
346 }, 356 },
347 /** 357 /**
348 * #!zh: renderCanvas 将拖拽过来的组件渲染到中间画布 上 358 * #!zh: renderCanvas 将拖拽过来的组件渲染到中间画布 上
@@ -357,16 +367,8 @@ const Editor = { @@ -357,16 +367,8 @@ const Editor = {
357 {elements.map((element, index) => { 367 {elements.map((element, index) => {
358 return (() => { 368 return (() => {
359 const data = { 369 const data = {
360 - style: {  
361 - top: '100px',  
362 - fontSize: '16px',  
363 - textAlign: 'center',  
364 - color: 'orange',  
365 - width: '100px',  
366 - height: '30px',  
367 - position: 'absolute'  
368 - },  
369 - on: { 370 + style: element.getStyle(),
  371 + nativeOn: {
370 click: this.setCurrentEditingElement.bind(this, element) 372 click: this.setCurrentEditingElement.bind(this, element)
371 } 373 }
372 } 374 }
@@ -404,27 +406,54 @@ const Editor = { @@ -404,27 +406,54 @@ const Editor = {
404 </el-tabs> 406 </el-tabs>
405 ) 407 )
406 }, 408 },
407 - renderPropsEditorPanel () {  
408 - return (<EditorPanel />) 409 + renderPropsEditorPanel (h) {
  410 + if (!this.editingElement) return (<span>请先选择一个元素</span>)
  411 + const editingElement = this.editingElement
  412 + const propsConfig = editingElement.editorConfig.propsConfig
  413 + return (
  414 + <el-form ref="form" label-width="80px">
  415 + {
  416 + Object.keys(propsConfig).map(propKey => {
  417 + const item = propsConfig[propKey]
  418 + // https://vuejs.org/v2/guide/render-function.html
  419 + const data = {
  420 + props: {
  421 + ...item.prop,
  422 + // https://vuejs.org/v2/guide/render-function.html#v-model
  423 + ...{ value: editingElement[propKey] || item.defaultPropValue }
  424 + },
  425 + on: {
  426 + // https://vuejs.org/v2/guide/render-function.html#v-model
  427 + input (value) {
  428 + editingElement[propKey] = value
  429 + }
  430 + }
  431 + }
  432 + return (
  433 + <el-form-item label={item.label}>
  434 + { h(item.type, data) }
  435 + </el-form-item>
  436 + )
  437 + })
  438 + }
  439 + </el-form>
  440 + )
409 } 441 }
410 }, 442 },
411 render (h) { 443 render (h) {
412 return ( 444 return (
413 - <div style='height: 100vh;'>  
414 - <div id='designer-page'>  
415 - <div class='el-col-5'>  
416 - { this.renderPluginListPanel() }  
417 - </div>  
418 - <div class='el-col-13'>  
419 - <div class='canvas-wrapper'>  
420 - { this.renderCanvas(h, this.elements) }  
421 - { this.hasEleEditing && <Shape elementStyle={this.editingElement.style || {}} /> }  
422 - </div>  
423 - </div>  
424 - <div class='el-col-6'>  
425 - { this.renderPropsEditorPanel() } 445 + <div id='designer-page'>
  446 + <div class='el-col-5'>
  447 + { this.renderPluginListPanel() }
  448 + </div>
  449 + <div class='el-col-13'>
  450 + <div class='canvas-wrapper'>
  451 + { this.renderCanvas(h, this.elements) }
426 </div> 452 </div>
427 </div> 453 </div>
  454 + <div class='el-col-6' style="border-left: 1px solid #eee;">
  455 + { this.renderPropsEditorPanel(h) }
  456 + </div>
428 </div> 457 </div>
429 ) 458 )
430 } 459 }
@@ -439,13 +468,6 @@ export default { @@ -439,13 +468,6 @@ export default {
439 } 468 }
440 }, 469 },
441 methods: { 470 methods: {
442 - getPropsDefaultValue (pluginName) {  
443 - const defaultPropsValue = {}  
444 - const component = this.$options.components[pluginName]  
445 - const propConfig = component.editorConfig.propConfig  
446 - Object.keys(propConfig).forEach(key => { defaultPropsValue[key] = propConfig[key].widgetProps.value })  
447 - return defaultPropsValue  
448 - },  
449 mixinPlugins2Editor () { 471 mixinPlugins2Editor () {
450 PluginList.forEach(plugin => { 472 PluginList.forEach(plugin => {
451 this.$options.components[plugin.name] = plugin.component 473 this.$options.components[plugin.name] = plugin.component