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