Commit c784e56d9c7ae9b91a524b1ad3b1a8c28f0f8d9e

Authored by ly525
1 parent abd9e622

feat(page): support copy, delete page

README.en.md
@@ -15,8 +15,11 @@ English | [简体中文](./README.md) @@ -15,8 +15,11 @@ English | [简体中文](./README.md)
15 - [x] Edit Element (Canvas) 15 - [x] Edit Element (Canvas)
16 - [x] Copy Element (Canvas) 16 - [x] Copy Element (Canvas)
17 - [x] Delete Element (Canvas) 17 - [x] Delete Element (Canvas)
18 - - [ ] Page: add, copy, delete  
19 - - [x] Preview 18 + - [x] Edit Page
  19 + - [x] Copy Page
  20 + - [x] Delete Page
  21 + - [x] Quick Preview
  22 + - [x] Undo、Redo
20 23
21 2. Plugin System 24 2. Plugin System
22 25
README.md
@@ -19,7 +19,9 @@ @@ -19,7 +19,9 @@
19 - [x] 元素: 复制(画布) 19 - [x] 元素: 复制(画布)
20 - [x] 元素: 删除(画布) 20 - [x] 元素: 删除(画布)
21 - [x] 元素: 编辑(画布) 21 - [x] 元素: 编辑(画布)
22 - - [ ] 页面:新增、复制、删除 22 + - [x] 页面:新增
  23 + - [x] 页面:复制
  24 + - [x] 页面:删除
23 - [x] 快速预览 25 - [x] 快速预览
24 - [x] 撤销、重做 26 - [x] 撤销、重做
25 27
front-end/h5/src/components/core/editor/index.js
@@ -79,8 +79,8 @@ export default { @@ -79,8 +79,8 @@ export default {
79 </a> 79 </a>
80 <a-menu slot="overlay" onClick={({ key }) => { this.pageManager({ type: key }) }}> 80 <a-menu slot="overlay" onClick={({ key }) => { this.pageManager({ type: key }) }}>
81 <a-menu-item key="add"><a-icon type="user" />新增页面</a-menu-item> 81 <a-menu-item key="add"><a-icon type="user" />新增页面</a-menu-item>
82 - {/* <a-menu-item key="copy"><a-icon type="user" />复制页面</a-menu-item> */}  
83 - {/* <a-menu-item key="delete"><a-icon type="user" />删除页面</a-menu-item> */} 82 + <a-menu-item key="copy"><a-icon type="user" />复制页面</a-menu-item>
  83 + <a-menu-item key="delete"><a-icon type="user" />删除页面</a-menu-item>
84 </a-menu> 84 </a-menu>
85 </a-dropdown> 85 </a-dropdown>
86 </span> 86 </span>
front-end/h5/src/components/core/models/element.js
  1 +const clone = (value) => JSON.parse(JSON.stringify(value))
1 2
2 const defaultProps = { 3 const defaultProps = {
3 top: 100, 4 top: 100,
@@ -16,14 +17,18 @@ class Element { @@ -16,14 +17,18 @@ class Element {
16 this.name = ele.name 17 this.name = ele.name
17 this.uuid = +new Date() 18 this.uuid = +new Date()
18 /** 19 /**
  20 + * #!zh:
19 * 之前版本代码:https://github.com/ly525/luban-h5/blob/a7875cbc73c0d18bc2459985ca3ce1d4dc44f141/front-end/h5/src/components/core/models/element.js#L21 21 * 之前版本代码:https://github.com/ly525/luban-h5/blob/a7875cbc73c0d18bc2459985ca3ce1d4dc44f141/front-end/h5/src/components/core/models/element.js#L21
20 * 1.之前的版本为:this.pluginProps = {}, 改为下面的版本 22 * 1.之前的版本为:this.pluginProps = {}, 改为下面的版本
21 * 是因为要支持[复制画布上的元素],所以需要先使用 ele.pluginProps 进行初始化(也就是拷贝之前的元素的值) 23 * 是因为要支持[复制画布上的元素],所以需要先使用 ele.pluginProps 进行初始化(也就是拷贝之前的元素的值)
22 * 24 *
23 * 2. 移除 this.init() 原因是:如果是 复制元素,则 init 会把 copy 的值重新覆盖为初始值,copy 无效 25 * 2. 移除 this.init() 原因是:如果是 复制元素,则 init 会把 copy 的值重新覆盖为初始值,copy 无效
  26 + *
  27 + * 3. 为何需要 clone,因为会有 element.clone() 以及 page.clone(),
  28 + * element.pluginProps 和 elementcommonStyle 是引用类型,如果不做 deep_clone 可能会出现意外错误
24 */ 29 */
25 - this.pluginProps = ele.pluginProps || this.getDefaultPluginProps(ele.editorConfig || {})  
26 - this.commonStyle = ele.commonStyle || this.getDefaultCommonStyle() 30 + this.pluginProps = clone(ele.pluginProps) || this.getDefaultPluginProps(ele.editorConfig || {})
  31 + this.commonStyle = clone(ele.commonStyle) || this.getDefaultCommonStyle()
27 this.events = [] 32 this.events = []
28 } 33 }
29 34
@@ -74,7 +79,7 @@ class Element { @@ -74,7 +79,7 @@ class Element {
74 clone () { 79 clone () {
75 return new Element({ 80 return new Element({
76 name: this.name, 81 name: this.name,
77 - pluginProps: JSON.parse(JSON.stringify(this.pluginProps)), 82 + pluginProps: this.pluginProps,
78 commonStyle: { 83 commonStyle: {
79 ...this.commonStyle, 84 ...this.commonStyle,
80 top: this.commonStyle.top + 20, 85 top: this.commonStyle.top + 20,
front-end/h5/src/components/core/models/page.js
  1 +import Element from '../models/element'
  2 +
1 class Page { 3 class Page {
2 constructor (page = {}) { 4 constructor (page = {}) {
  5 + this.uuid = +new Date()
3 this.elements = page.elements || [] 6 this.elements = page.elements || []
4 } 7 }
  8 +
  9 + clone () {
  10 + const elements = this.elements.map(element => new Element(element))
  11 + return new Page({ elements })
  12 + }
5 } 13 }
6 14
7 export default Page 15 export default Page
front-end/h5/src/store/modules/page.js
@@ -26,10 +26,12 @@ export const mutations = { @@ -26,10 +26,12 @@ export const mutations = {
26 state.work.pages.push(state.editingPage.clone()) 26 state.work.pages.push(state.editingPage.clone())
27 break 27 break
28 case 'delete': 28 case 'delete':
  29 + if (state.work.pages.length === 1) return // #!zh: 作品中至少需要保留一个页面,TODO 需要在页面中提示用户此信息
  30 +
29 const { work, editingPage } = state 31 const { work, editingPage } = state
30 - let index = work.pages.findIndex(e => e.uuid === editingPage.uuid) 32 + let index = work.pages.findIndex(page => page.uuid === editingPage.uuid)
31 if (index !== -1) { 33 if (index !== -1) {
32 - let newPages = work.slice() 34 + let newPages = work.pages.slice()
33 newPages.splice(index, 1) 35 newPages.splice(index, 1)
34 state.work.pages = newPages 36 state.work.pages = newPages
35 } 37 }
front-end/h5/src/store/modules/work.js
1 // import Work from '../../components/core/models/work' 1 // import Work from '../../components/core/models/work'
2 import Element from '../../components/core/models/element' 2 import Element from '../../components/core/models/element'
3 import strapi from '../../utils/strapi' 3 import strapi from '../../utils/strapi'
  4 +import Page from '../../components/core/models/page'
4 5
5 export const actions = { 6 export const actions = {
6 previewWork ({ commit }, payload = {}) { 7 previewWork ({ commit }, payload = {}) {
@@ -32,8 +33,9 @@ export const actions = { @@ -32,8 +33,9 @@ export const actions = {
32 // mutations 33 // mutations
33 export const mutations = { 34 export const mutations = {
34 setWork (state, work) { 35 setWork (state, work) {
35 - work.pages.forEach(page => { 36 + work.pages = work.pages.map(page => {
36 page.elements = page.elements.map(element => new Element(element)) 37 page.elements = page.elements.map(element => new Element(element))
  38 + return new Page(page)
37 }) 39 })
38 state.work = work 40 state.work = work
39 }, 41 },