Commit 84e312efa23eb6f2f4e63610abc33f00510a336b

Authored by ly525
1 parent f809cdf8

refactor: detach the plugin props editor from the plugin; zh: 将组件和组件属性编辑器进行分离

front-end/h5/src/components/core/editor/edit-panel/props.js
  1 +import Vue from 'vue'
1 2 import { mapState, mapActions } from 'vuex'
2 3 import { getVM } from '../../../../utils/element'
3 4  
4 5 export default {
  6 + data: () => ({
  7 + loadCustomEditorFlag: false
  8 + }),
5 9 props: {
6 10 layout: {
7 11 type: String,
... ... @@ -9,12 +13,31 @@ export default {
9 13 }
10 14 },
11 15 computed: {
12   - ...mapState('editor', ['editingElement', 'editingElementEditorConfig'])
  16 + ...mapState('editor', ['editingElement', 'editingElementEditorConfig']),
  17 + customEditorName () {
  18 + return `${this.editingElement.name}-custom-editor`
  19 + }
13 20 },
14 21 methods: {
15 22 ...mapActions('editor', [
16 23 'setEditingElement'
17 24 ]),
  25 + loadCustomEditorForPlugin () {
  26 + this.loadCustomEditorFlag = false
  27 + if (!this.editingElement) return
  28 +
  29 + if (Vue.component(this.customEditorName)) {
  30 + this.loadCustomEditorFlag = true
  31 + } else {
  32 + import(`../../../plugins/${this.editingElement.name}__editor`).then(component => {
  33 + this.loadCustomEditorFlag = true
  34 + Vue.component(this.customEditorName, component.default)
  35 + }).catch(err => {
  36 + console.log(err)
  37 + console.warn('没有发现组件对应的编辑器')
  38 + })
  39 + }
  40 + },
18 41 /**
19 42 * 将插件属性的 自定义增强编辑器注入 属性编辑面板中
20 43 */
... ... @@ -37,9 +60,18 @@ export default {
37 60 layout={this.layout}
38 61 >
39 62 {
  63 + // plugin-custom-editor
  64 + this.loadCustomEditorFlag &&
  65 + h(this.customEditorName, {
  66 + props: {
  67 + elementProps: editingElement.pluginProps
  68 + }
  69 + })
  70 + }
  71 + {
40 72 Object
41 73 .entries(props)
42   - .filter(([propKey, obj]) => obj.editor)
  74 + .filter(([propKey, obj]) => obj.editor && !obj.editor.custom)
43 75 .map(([propKey, obj]) => {
44 76 const item = obj.editor
45 77 // https://vuejs.org/v2/guide/render-function.html
... ... @@ -92,5 +124,8 @@ export default {
92 124 if (!ele) return (<span>{this.$t('editor.editPanel.common.empty')}</span>)
93 125 this.mixinEnhancedPropsEditor(ele)
94 126 return this.renderPropsEditorPanel(h, ele)
  127 + },
  128 + created () {
  129 + window.getEditorApp.$on('setEditingElement', this.loadCustomEditorForPlugin)
95 130 }
96 131 }
... ...
front-end/h5/src/components/plugins/lbp-slide.js
1 1 import { Swipe, SwipeItem } from 'vant'
2 2 import 'vant/lib/swipe/style'
3 3 import 'vant/lib/swipe-item/style'
4   -import ImageGallery from '@/components/core/support/image-gallery/gallery.js'
5 4  
6 5 const defaultItems = [
7 6 {
... ... @@ -12,13 +11,6 @@ const defaultItems = [
12 11 }
13 12 ]
14 13  
15   -function getDefaultDataSource () {
16   - return {
17   - activeIndex: 0,
18   - items: defaultItems.slice(0)
19   - }
20   -}
21   -
22 14 export default {
23 15 name: 'lbp-slide',
24 16 props: {
... ... @@ -28,18 +20,7 @@ export default {
28 20 editor: {
29 21 type: 'a-input-number',
30 22 label: '间隔时间',
31   - require: true,
32   - defaultPropValue: 4000
33   - }
34   - },
35   - dataSource: {
36   - type: Object,
37   - default: () => getDefaultDataSource(),
38   - editor: {
39   - type: 'lbs-slide-items-editor',
40   - label: '图片列表',
41   - require: true,
42   - defaultPropValue: getDefaultDataSource()
  23 + require: true
43 24 }
44 25 },
45 26 editorMode: {
... ... @@ -48,87 +29,21 @@ export default {
48 29 },
49 30 activeIndex: {
50 31 type: Number,
51   - default: 0
  32 + default: 0,
  33 + editor: {
  34 + custom: true
  35 + }
  36 + },
  37 + items: {
  38 + type: Array,
  39 + default: () => defaultItems.slice(0),
  40 + editor: {
  41 + custom: true
  42 + }
52 43 }
53 44 },
54 45 editorConfig: {
55 46 components: {
56   - 'lbs-slide-items-editor': {
57   - render () {
58   - const currentItem = this.innerItems[this.current - 1] || {}
59   - return <div>
60   - {
61   - <a-pagination
62   - current={this.current}
63   - onChange={(page) => {
64   - this.current = page
65   - this.$emit('change', {
66   - items: this.innerItems,
67   - activeIndex: page - 1
68   - })
69   - }}
70   - size="small"
71   - total={this.innerItems.length}
72   - defaultPageSize={1}
73   - itemRender={this.itemRender}
74   - />
75   - }
76   - <ImageGallery
77   - style={{ margin: '16px 0' }}
78   - value={currentItem.image}
79   - onChange={url => {
80   - currentItem.image = url
81   - }}
82   - />
83   - </div>
84   - },
85   - props: {
86   - value: {
87   - type: Object,
88   - default: () => getDefaultDataSource()
89   - }
90   - },
91   - computed: {
92   - innerItems () {
93   - return this.value.items
94   - }
95   - },
96   - data: () => ({
97   - current: 1
98   - }),
99   - methods: {
100   - itemRender (current, type, originalElement) {
101   - if (type === 'prev') {
102   - return <a-button style={{ marginRight: '8px' }} size="small" icon="minus" onClick={() => this.minus(current)} disabled={this.innerItems.length === 1}></a-button>
103   - } else if (type === 'next') {
104   - return <a-button style={{ marginLeft: '8px' }} size="small" icon="plus" onClick={this.add}></a-button>
105   - }
106   - return originalElement
107   - },
108   - add () {
109   - this.$emit('change', {
110   - activeIndex: this.innerItems.length,
111   - items: [
112   - ...this.innerItems,
113   - {
114   - image: '',
115   - value: `选项${this.innerItems.length + 1}-value`,
116   - label: `选项${this.innerItems.length + 1}-label`
117   - }
118   - ]
119   - })
120   - },
121   - minus (index) {
122   - if (this.innerItems.length === 1) return
123   - const items = this.innerItems.slice(0)
124   - items.splice(index, 1)
125   - this.$emit('change', {
126   - items,
127   - activeIndex: index > 0 ? index - 1 : 0
128   - })
129   - }
130   - }
131   - }
132 47 }
133 48 },
134 49 mounted () {
... ... @@ -137,7 +52,7 @@ export default {
137 52  
138 53 },
139 54 render () {
140   - const { items, activeIndex } = this.dataSource
  55 + const { items, activeIndex } = this
141 56 return (
142 57 this.editorMode === 'edit'
143 58 ? items.length && <img src={items[activeIndex].image} />
... ...
front-end/h5/src/components/plugins/lbp-slide__editor.js 0 → 100644
  1 +import ImageGallery from '@/components/core/support/image-gallery/gallery.js'
  2 +
  3 +export default {
  4 + props: {
  5 + elementProps: {
  6 + type: Object,
  7 + default: () => ({
  8 + items: [],
  9 + activeIndex: 0
  10 + })
  11 + }
  12 + },
  13 + computed: {
  14 + innerItems () {
  15 + return this.elementProps.items
  16 + }
  17 + },
  18 + data: () => ({
  19 + current: 1
  20 + }),
  21 + methods: {
  22 + itemRender (current, type, originalElement) {
  23 + if (type === 'prev') {
  24 + return <a-button style={{ marginRight: '8px' }} size="small" icon="minus" onClick={() => this.minus(current)} disabled={this.innerItems.length === 1}></a-button>
  25 + } else if (type === 'next') {
  26 + return <a-button style={{ marginLeft: '8px' }} size="small" icon="plus" onClick={this.add}></a-button>
  27 + }
  28 + return originalElement
  29 + },
  30 + add () {
  31 + // this.$emit('change', {
  32 + // activeIndex: this.innerItems.length,
  33 + // items: [
  34 + // ...this.innerItems,
  35 + // {
  36 + // image: '',
  37 + // value: `选项${this.innerItems.length + 1}-value`,
  38 + // label: `选项${this.innerItems.length + 1}-label`
  39 + // }
  40 + // ]
  41 + // })
  42 + this.elementProps.items.push({
  43 + image: '',
  44 + value: `选项${this.innerItems.length + 1}-value`,
  45 + label: `选项${this.innerItems.length + 1}-label`
  46 + })
  47 + },
  48 + minus (index) {
  49 + if (this.innerItems.length === 1) return
  50 + this.elementProps.items.splice(index, 1)
  51 + this.elementProps.activeIndex = index > 0 ? index - 1 : 0
  52 + // const items = this.innerItems.slice(0)
  53 + // items.splice(index, 1)
  54 + // this.$emit('change', {
  55 + // items,
  56 + // activeIndex: index > 0 ? index - 1 : 0
  57 + // })
  58 + }
  59 + },
  60 + render () {
  61 + const currentItem = this.innerItems[this.current - 1] || {}
  62 + return <div>
  63 + {
  64 + <a-pagination
  65 + current={this.current}
  66 + onChange={(page) => {
  67 + this.current = page
  68 +
  69 + this.activeIndex = page - 1
  70 + // this.$emit('change', {
  71 + // items: this.innerItems,
  72 + // activeIndex: page - 1
  73 + // })
  74 + }}
  75 + size="small"
  76 + total={this.innerItems.length}
  77 + defaultPageSize={1}
  78 + itemRender={this.itemRender}
  79 + />
  80 + }
  81 + <ImageGallery
  82 + style={{ margin: '16px 0' }}
  83 + value={currentItem.image}
  84 + onChange={url => {
  85 + currentItem.image = url
  86 + }}
  87 + />
  88 + </div>
  89 + }
  90 +
  91 +}
... ...
front-end/h5/src/store/modules/element.js
... ... @@ -8,6 +8,8 @@ export const actions = {
8 8  
9 9 const vm = (payload && payload.name) ? getEditorConfigForEditingElement(payload.name) : null
10 10 commit('setEditingElementEditorConfig', vm)
  11 +
  12 + window.getEditorApp.$emit('setEditingElement')
11 13 },
12 14 setElementPosition ({ commit }, payload) {
13 15 commit('setElementCommonStyle', payload)
... ...