Commit 4a1836d1d08ac655f35840327379cba63029c630
1 parent
0df8bee6
feat(editor) <en> suppport update page title <zh> 支持修改页面标题
Showing
4 changed files
with
75 additions
and
12 deletions
front-end/h5/src/components/core/editor/index.js
| @@ -163,6 +163,10 @@ export default { | @@ -163,6 +163,10 @@ export default { | ||
| 163 | onSelectMenuItem={(menuKey) => { | 163 | onSelectMenuItem={(menuKey) => { |
| 164 | this.pageManager({ type: menuKey }) | 164 | this.pageManager({ type: menuKey }) |
| 165 | }} | 165 | }} |
| 166 | + onEditTitle={({ pageIndexForEditingTitle, newTitle }) => { | ||
| 167 | + this.pageManager({ type: 'editTitle', value: { pageIndexForEditingTitle, newTitle } }) | ||
| 168 | + this.saveWork({ isSaveCover: false }) | ||
| 169 | + }} | ||
| 166 | onSelectPage={(pageIndex) => { this.setEditingPage(pageIndex) }} | 170 | onSelectPage={(pageIndex) => { this.setEditingPage(pageIndex) }} |
| 167 | /> | 171 | /> |
| 168 | </a-tab-pane> | 172 | </a-tab-pane> |
front-end/h5/src/components/core/editor/page-manager/index.js
| @@ -10,12 +10,62 @@ export default { | @@ -10,12 +10,62 @@ export default { | ||
| 10 | default: () => {} | 10 | default: () => {} |
| 11 | } | 11 | } |
| 12 | }, | 12 | }, |
| 13 | + data: () => ({ | ||
| 14 | + hoverIndex: -1, // 显示编辑按钮 | ||
| 15 | + editingTitle: '' // 临时缓存当前编辑的 title,点击 Yes 再真正用其更新 page title | ||
| 16 | + }), | ||
| 13 | methods: { | 17 | methods: { |
| 18 | + getTitle (page, index) { | ||
| 19 | + return page.title || this.$t('editor.pageManager.title', { index }) | ||
| 20 | + }, | ||
| 21 | + _renderEditTitle (page, index) { | ||
| 22 | + return ( | ||
| 23 | + <a-popconfirm | ||
| 24 | + placement="bottom" | ||
| 25 | + onConfirm={() => { | ||
| 26 | + this.$emit('editTitle', { newTitle: this.editingTitle, pageIndexForEditingTitle: index }) | ||
| 27 | + }} | ||
| 28 | + onCancel={() => {}} | ||
| 29 | + okText="Yes" | ||
| 30 | + cancelText="No" | ||
| 31 | + > | ||
| 32 | + <a-input | ||
| 33 | + slot="title" | ||
| 34 | + value={this.editingTitle} | ||
| 35 | + size="small" | ||
| 36 | + onChange={e => { | ||
| 37 | + this.editingTitle = e.target.value | ||
| 38 | + }} | ||
| 39 | + > | ||
| 40 | + </a-input> | ||
| 41 | + <a-icon type="edit" onClick={(e) => { | ||
| 42 | + e.stopPropagation() // 将 click icon 与 click page item 隔离开。编辑标题的同时不要切换页面 | ||
| 43 | + this.editingTitle = this.getTitle(page, index) | ||
| 44 | + }}/> | ||
| 45 | + </a-popconfirm> | ||
| 46 | + ) | ||
| 47 | + }, | ||
| 48 | + _renderTitleMenu (page, index) { | ||
| 49 | + const addPageText = this.$t('editor.pageManager.action.add') | ||
| 50 | + const copyPageText = this.$t('editor.pageManager.action.copy') | ||
| 51 | + const deletePageText = this.$t('editor.pageManager.action.delete') | ||
| 52 | + return ( | ||
| 53 | + <a-dropdown trigger={['hover']} placement='bottomCenter'> | ||
| 54 | + <a class="ant-dropdown-link" href="#" class="ml-2"><a-icon type="down" /></a> | ||
| 55 | + <a-menu slot="overlay" onClick={({ key }) => this.$emit('selectMenuItem', key)}> | ||
| 56 | + <a-menu-item key="add"><a-icon type="plus" />{addPageText}</a-menu-item> | ||
| 57 | + <a-menu-item key="copy"><a-icon type="copy" />{copyPageText}</a-menu-item> | ||
| 58 | + <a-menu-item key="delete"><a-icon type="delete" />{deletePageText}</a-menu-item> | ||
| 59 | + </a-menu> | ||
| 60 | + </a-dropdown> | ||
| 61 | + ) | ||
| 62 | + }, | ||
| 63 | + onLeave () { | ||
| 64 | + this.hoverIndex = -1 | ||
| 65 | + } | ||
| 14 | }, | 66 | }, |
| 15 | render (h) { | 67 | render (h) { |
| 16 | const addPageText = this.$t('editor.pageManager.action.add') | 68 | const addPageText = this.$t('editor.pageManager.action.add') |
| 17 | - const copyPageText = this.$t('editor.pageManager.action.copy') | ||
| 18 | - const deletePageText = this.$t('editor.pageManager.action.delete') | ||
| 19 | return ( | 69 | return ( |
| 20 | <div class="page-manager-panel"> | 70 | <div class="page-manager-panel"> |
| 21 | { | 71 | { |
| @@ -27,18 +77,22 @@ export default { | @@ -27,18 +77,22 @@ export default { | ||
| 27 | page.uuid === this.editingPage.uuid && 'active' | 77 | page.uuid === this.editingPage.uuid && 'active' |
| 28 | ]} | 78 | ]} |
| 29 | onClick={() => { this.$emit('selectPage', index) }} | 79 | onClick={() => { this.$emit('selectPage', index) }} |
| 80 | + // https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VHover/VHover.ts | ||
| 81 | + onMouseenter={() => { this.hoverIndex = index }} | ||
| 30 | > | 82 | > |
| 31 | {/* #!en: Page<Index> */} | 83 | {/* #!en: Page<Index> */} |
| 32 | {/* #!zh: 第<Index>页面 */} | 84 | {/* #!zh: 第<Index>页面 */} |
| 33 | - <span>{this.$t('editor.pageManager.title', { index })}</span> | ||
| 34 | - <a-dropdown trigger={['hover']} placement='bottomCenter'> | ||
| 35 | - <a class="ant-dropdown-link" href="#"><a-icon type="down" /></a> | ||
| 36 | - <a-menu slot="overlay" onClick={({ key }) => { this.$emit('selectMenuItem', key) }}> | ||
| 37 | - <a-menu-item key="add"><a-icon type="user" />{addPageText}</a-menu-item> | ||
| 38 | - <a-menu-item key="copy"><a-icon type="user" />{copyPageText}</a-menu-item> | ||
| 39 | - <a-menu-item key="delete"><a-icon type="user" />{deletePageText}</a-menu-item> | ||
| 40 | - </a-menu> | ||
| 41 | - </a-dropdown> | 85 | + <span> |
| 86 | + <a-badge | ||
| 87 | + count={index + 1} | ||
| 88 | + numberStyle={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset' }} | ||
| 89 | + /> | ||
| 90 | + <span class="ml-3">{this.getTitle(page, index)}</span> | ||
| 91 | + </span> | ||
| 92 | + <span> | ||
| 93 | + {this.hoverIndex === index && this._renderEditTitle(page, index)} | ||
| 94 | + {this._renderTitleMenu(page, index)} | ||
| 95 | + </span> | ||
| 42 | </span> | 96 | </span> |
| 43 | )) | 97 | )) |
| 44 | } | 98 | } |
front-end/h5/src/components/core/models/page.js
| @@ -4,12 +4,13 @@ import LbpBackground from '../../plugins/lbp-background' | @@ -4,12 +4,13 @@ import LbpBackground from '../../plugins/lbp-background' | ||
| 4 | class Page { | 4 | class Page { |
| 5 | constructor (page = {}) { | 5 | constructor (page = {}) { |
| 6 | this.uuid = +new Date() | 6 | this.uuid = +new Date() |
| 7 | + this.title = page.title || '' | ||
| 7 | this.elements = page.elements || [new Element(LbpBackground)] | 8 | this.elements = page.elements || [new Element(LbpBackground)] |
| 8 | } | 9 | } |
| 9 | 10 | ||
| 10 | clone () { | 11 | clone () { |
| 11 | const elements = this.elements.map(element => new Element(element)) | 12 | const elements = this.elements.map(element => new Element(element)) |
| 12 | - return new Page({ elements }) | 13 | + return new Page({ title: this.title, elements }) |
| 13 | } | 14 | } |
| 14 | } | 15 | } |
| 15 | 16 |
front-end/h5/src/store/modules/page.js
| @@ -17,6 +17,10 @@ export const mutations = { | @@ -17,6 +17,10 @@ export const mutations = { | ||
| 17 | }, | 17 | }, |
| 18 | pageManager (state, { type, value }) { | 18 | pageManager (state, { type, value }) { |
| 19 | switch (type) { | 19 | switch (type) { |
| 20 | + case 'editTitle': | ||
| 21 | + const { pageIndexForEditingTitle, newTitle } = value | ||
| 22 | + state.work.pages[pageIndexForEditingTitle].title = newTitle | ||
| 23 | + break | ||
| 20 | case 'add': | 24 | case 'add': |
| 21 | const page = new Page(value) | 25 | const page = new Page(value) |
| 22 | state.work.pages.push(page) | 26 | state.work.pages.push(page) |