From 4fc25241fe1c89aadc35e58fef22f12137303377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=B1=E8=A3=A4=E8=A1=A9?= <panfree23@gmail.com> Date: Wed, 30 May 2018 15:25:08 +0800 Subject: [PATCH] refactor example demo (#713) * refactor: Adjust the example directory structure * perf form demo * refine editor-slide-upload css * refine demo --- src/api/article.js | 5 +- .../Tinymce/components/editorImage.vue | 7 +- src/icons/svg/edit.svg | 1 + src/icons/svg/list.svg | 1 + src/lang/en.js | 5 +- src/lang/zh.js | 5 +- src/mock/article.js | 34 ++-- src/router/index.js | 63 +++--- src/utils/index.js | 4 + .../components/ArticleDetail.vue | 189 ++++++------------ .../example/components/Dropdown/Comment.vue | 31 +++ .../example/components/Dropdown/Platform.vue | 40 ++++ .../example/components/Dropdown/SourceUrl.vue | 31 +++ .../example/components/Dropdown/index.js | 3 + src/views/example/components/Warning.vue | 9 + src/views/{form => example}/create.vue | 0 src/views/{form => example}/edit.vue | 0 src/views/example/list.vue | 121 +++++++++++ src/views/example/table/index.vue | 18 -- src/views/layout/components/AppMain.vue | 8 +- src/views/layout/components/TagsView.vue | 2 +- .../{example => }/tab/components/tabPane.vue | 0 src/views/{example => }/tab/index.vue | 2 + .../{example => }/table/complexTable.vue | 2 +- src/views/{example => }/table/dragTable.vue | 2 +- .../table/dynamicTable/fixedThead.vue | 0 .../table/dynamicTable/index.vue | 0 .../table/dynamicTable/unfixedThead.vue | 0 .../{example => }/table/inlineEditTable.vue | 2 +- .../table/treeTable/customEval.js | 0 .../table/treeTable/customTreeTable.vue | 0 .../table/treeTable/treeTable.vue | 0 32 files changed, 376 insertions(+), 209 deletions(-) create mode 100644 src/icons/svg/edit.svg create mode 100644 src/icons/svg/list.svg rename src/views/{form => example}/components/ArticleDetail.vue (52%) create mode 100644 src/views/example/components/Dropdown/Comment.vue create mode 100644 src/views/example/components/Dropdown/Platform.vue create mode 100644 src/views/example/components/Dropdown/SourceUrl.vue create mode 100644 src/views/example/components/Dropdown/index.js create mode 100644 src/views/example/components/Warning.vue rename src/views/{form => example}/create.vue (100%) rename src/views/{form => example}/edit.vue (100%) create mode 100644 src/views/example/list.vue delete mode 100644 src/views/example/table/index.vue rename src/views/{example => }/tab/components/tabPane.vue (100%) rename src/views/{example => }/tab/index.vue (85%) rename src/views/{example => }/table/complexTable.vue (99%) rename src/views/{example => }/table/dragTable.vue (98%) rename src/views/{example => }/table/dynamicTable/fixedThead.vue (100%) rename src/views/{example => }/table/dynamicTable/index.vue (100%) rename src/views/{example => }/table/dynamicTable/unfixedThead.vue (100%) rename src/views/{example => }/table/inlineEditTable.vue (98%) rename src/views/{example => }/table/treeTable/customEval.js (100%) rename src/views/{example => }/table/treeTable/customTreeTable.vue (100%) rename src/views/{example => }/table/treeTable/treeTable.vue (100%) diff --git a/src/api/article.js b/src/api/article.js index 9eacd90d..f54b8af6 100644 --- a/src/api/article.js +++ b/src/api/article.js @@ -8,10 +8,11 @@ export function fetchList(query) { }) } -export function fetchArticle() { +export function fetchArticle(id) { return request({ url: '/article/detail', - method: 'get' + method: 'get', + params: { id } }) } diff --git a/src/components/Tinymce/components/editorImage.vue b/src/components/Tinymce/components/editorImage.vue index eee2c5f2..dd46916a 100644 --- a/src/components/Tinymce/components/editorImage.vue +++ b/src/components/Tinymce/components/editorImage.vue @@ -87,9 +87,10 @@ export default { </script> <style rel="stylesheet/scss" lang="scss" scoped> -.upload-container { - .editor-slide-upload { - margin-bottom: 20px; +.editor-slide-upload { + margin-bottom: 20px; + /deep/ .el-upload--picture-card { + width: 100%; } } </style> diff --git a/src/icons/svg/edit.svg b/src/icons/svg/edit.svg new file mode 100644 index 00000000..5c77d97a --- /dev/null +++ b/src/icons/svg/edit.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1525760397212" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2919" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M860 504c-19.9 0-36 16.1-36 36 0 1.4 0.1 2.7 0.2 4h-0.2v344H136V200h376c19.9 0 36-16.1 36-36s-16.1-36-36-36H136c-39.8 0-72 32.2-72 72v688c0 39.8 32.2 72 72 72h688c39.8 0 72-32.2 72-72V544h-0.2c0.1-1.3 0.2-2.6 0.2-4 0-19.9-16.1-36-36-36z" p-id="2920"></path><path d="M1002.7 100.3L923.4 21c-28.1-28.1-73.9-27.9-102 0.2L424.2 418.4c-2.9 2.9-5.2 6.4-6.8 10.2L317.6 664c-5.6 13.2-1.7 26.5 6.8 35.1 8.5 8.6 21.9 12.5 35.2 6.9l235.5-99.7c3.8-1.6 7.2-3.9 10.2-6.8l397.2-397.2c28.1-28.1 28.3-73.9 0.2-102zM559.8 543l-137.4 58.2 58.2-137.4L759.4 185l79.2 79.2L559.8 543z m391.7-391.7l-62 62-79.2-79.2 62-62 0.2-0.2 79.2 79.2-0.2 0.2z" p-id="2921"></path></svg> \ No newline at end of file diff --git a/src/icons/svg/list.svg b/src/icons/svg/list.svg new file mode 100644 index 00000000..c45f4591 --- /dev/null +++ b/src/icons/svg/list.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1525761666409" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10880" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M107.2 212.8m-67.2 0a4.2 4.2 0 1 0 134.4 0 4.2 4.2 0 1 0-134.4 0Z" p-id="10881"></path><path d="M980.8 145.6 297.6 145.6c-9.6 0-16 8-16 16l0 102.4c0 9.6 8 16 16 16l683.2 0c9.6 0 16-8 16-16l0-102.4C996.8 152 988.8 145.6 980.8 145.6z" p-id="10882"></path><path d="M96 497.6m-67.2 0a4.2 4.2 0 1 0 134.4 0 4.2 4.2 0 1 0-134.4 0Z" p-id="10883"></path><path d="M968 430.4 284.8 430.4c-9.6 0-16 8-16 16l0 102.4c0 9.6 8 16 16 16l683.2 0c9.6 0 16-8 16-16l0-102.4C984 438.4 977.6 430.4 968 430.4z" p-id="10884"></path><path d="M96 795.2m-67.2 0a4.2 4.2 0 1 0 134.4 0 4.2 4.2 0 1 0-134.4 0Z" p-id="10885"></path><path d="M968 728 284.8 728c-9.6 0-16 8-16 16l0 102.4c0 9.6 8 16 16 16l683.2 0c9.6 0 16-8 16-16l0-102.4C984 736 977.6 728 968 728z" p-id="10886"></path></svg> \ No newline at end of file diff --git a/src/lang/en.js b/src/lang/en.js index f84f0de2..a7b1fa00 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -37,8 +37,9 @@ export default { customTreeTable: 'Custom TreeTable', tab: 'Tab', form: 'Form', - createForm: 'Create Form', - editForm: 'Edit Form', + createArticle: 'Create Article', + editArticle: 'Edit Article', + articleList: 'Article List', errorPages: 'Error Pages', page401: '401', page404: '404', diff --git a/src/lang/zh.js b/src/lang/zh.js index 6ef13eec..2b081331 100644 --- a/src/lang/zh.js +++ b/src/lang/zh.js @@ -37,8 +37,9 @@ export default { customTreeTable: 'è‡ªå®šä¹‰æ ‘è¡¨', tab: 'Tab', form: '表å•', - createForm: '创建表å•', - editForm: '编辑表å•', + createArticle: 'åˆ›å»ºæ–‡ç« ', + editArticle: 'ç¼–è¾‘æ–‡ç« ', + articleList: 'æ–‡ç« åˆ—è¡¨', errorPages: '错误页é¢', page401: '401', page404: '404', diff --git a/src/mock/article.js b/src/mock/article.js index 2f5b4583..45923ddd 100644 --- a/src/mock/article.js +++ b/src/mock/article.js @@ -4,6 +4,9 @@ import { param2Obj } from '@/utils' const List = [] const count = 100 +const baseContent = '<p>我是测试数æ®æˆ‘是测试数æ®</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>' +const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3' + for (let i = 0; i < count; i++) { List.push(Mock.mock({ id: '@increment', @@ -11,12 +14,17 @@ for (let i = 0; i < count; i++) { author: '@first', reviewer: '@first', title: '@title(5, 10)', + content_short: '我是测试数æ®', + content: baseContent, forecast: '@float(0, 100, 2, 2)', importance: '@integer(1, 3)', 'type|1': ['CN', 'US', 'JP', 'EU'], 'status|1': ['published', 'draft', 'deleted'], display_time: '@datetime', - pageviews: '@integer(300, 5000)' + comment_disabled: true, + pageviews: '@integer(300, 5000)', + image_uri, + platforms: ['a-platform'] })) } @@ -45,22 +53,14 @@ export default { getPv: () => ({ pvData: [{ key: 'PC', pv: 1024 }, { key: 'mobile', pv: 1024 }, { key: 'ios', pv: 1024 }, { key: 'android', pv: 1024 }] }), - getArticle: () => ({ - id: 120000000001, - author: { key: 'mockPan' }, - source_name: '原创作者', - category_item: [{ key: 'global', name: 'å…¨çƒ' }], - comment_disabled: true, - content: '<p>我是测试数æ®æˆ‘是测试数æ®</p><p><img class="wscnph" src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943" data-wscntype="image" data-wscnh="300" data-wscnw="400" data-mce-src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>"', - content_short: '我是测试数æ®', - display_time: +new Date(), - image_uri: 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3', - platforms: ['a-platform'], - source_uri: 'https://github.com/PanJiaChen/vue-element-admin', - status: 'published', - tags: [], - title: 'vue-element-admin' - }), + getArticle: (config) => { + const { id } = param2Obj(config.url) + for (const article of List) { + if (article.id === +id) { + return article + } + } + }, createArticle: () => ({ data: 'success' }), diff --git a/src/router/index.js b/src/router/index.js index ce43eec2..72eb22db 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -127,7 +127,6 @@ export const asyncRouterMap = [ { path: 'tinymce', component: _import('components-demo/tinymce'), name: 'tinymce-demo', meta: { title: 'tinymce' }}, { path: 'markdown', component: _import('components-demo/markdown'), name: 'markdown-demo', meta: { title: 'markdown' }}, { path: 'json-editor', component: _import('components-demo/jsonEditor'), name: 'jsonEditor-demo', meta: { title: 'jsonEditor' }}, - { path: 'dnd-list', component: _import('components-demo/dndList'), name: 'dndList-demo', meta: { title: 'dndList' }}, { path: 'splitpane', component: _import('components-demo/splitpane'), name: 'splitpane-demo', meta: { title: 'splitPane' }}, { path: 'avatar-upload', component: _import('components-demo/avatarUpload'), name: 'avatarUpload-demo', meta: { title: 'avatarUpload' }}, { path: 'dropzone', component: _import('components-demo/dropzone'), name: 'dropzone-demo', meta: { title: 'dropzone' }}, @@ -136,6 +135,7 @@ export const asyncRouterMap = [ { path: 'mixin', component: _import('components-demo/mixin'), name: 'componentMixin-demo', meta: { title: 'componentMixin' }}, { path: 'back-to-top', component: _import('components-demo/backToTop'), name: 'backToTop-demo', meta: { title: 'backToTop' }}, { path: 'drag-dialog', component: _import('components-demo/dragDialog'), name: 'dragDialog-demo', meta: { title: 'dragDialog' }}, + { path: 'dnd-list', component: _import('components-demo/dndList'), name: 'dndList-demo', meta: { title: 'dndList' }}, { path: 'drag-kanban', component: _import('components-demo/dragKanban'), name: 'dragKanban-demo', meta: { title: 'dragKanban' }} ] }, @@ -157,49 +157,48 @@ export const asyncRouterMap = [ }, { - path: '/example', + path: '/tab', component: Layout, - redirect: '/example/table/complex-table', - name: 'example', + children: [{ + path: 'index', + component: _import('tab/index'), + name: 'tab', + meta: { title: 'tab', icon: 'tab' } + }] + }, + + { + path: '/table', + component: Layout, + redirect: '/table/complex-table', + name: 'table', meta: { - title: 'example', - icon: 'example' + title: 'Table', + icon: 'table' }, children: [ - { - path: '/example/table', - component: _import('example/table/index'), - redirect: '/example/table/complex-table', - name: 'Table', - meta: { - title: 'Table', - icon: 'table' - }, - children: [ - { path: 'dynamic-table', component: _import('example/table/dynamicTable/index'), name: 'dynamicTable', meta: { title: 'dynamicTable' }}, - { path: 'drag-table', component: _import('example/table/dragTable'), name: 'dragTable', meta: { title: 'dragTable' }}, - { path: 'inline-edit-table', component: _import('example/table/inlineEditTable'), name: 'inlineEditTable', meta: { title: 'inlineEditTable' }}, - { path: 'tree-table', component: _import('example/table/treeTable/treeTable'), name: 'treeTableDemo', meta: { title: 'treeTable' }}, - { path: 'custom-tree-table', component: _import('example/table/treeTable/customTreeTable'), name: 'customTreeTableDemo', meta: { title: 'customTreeTable' }}, - { path: 'complex-table', component: _import('example/table/complexTable'), name: 'complexTable', meta: { title: 'complexTable' }} - ] - }, - { path: 'tab/index', icon: 'tab', component: _import('example/tab/index'), name: 'tab', meta: { title: 'tab' }} + { path: 'dynamic-table', component: _import('table/dynamicTable/index'), name: 'dynamicTable', meta: { title: 'dynamicTable' }}, + { path: 'drag-table', component: _import('table/dragTable'), name: 'dragTable', meta: { title: 'dragTable' }}, + { path: 'inline-edit-table', component: _import('table/inlineEditTable'), name: 'inlineEditTable', meta: { title: 'inlineEditTable' }}, + { path: 'tree-table', component: _import('table/treeTable/treeTable'), name: 'treeTableDemo', meta: { title: 'treeTable' }}, + { path: 'custom-tree-table', component: _import('table/treeTable/customTreeTable'), name: 'customTreeTableDemo', meta: { title: 'customTreeTable' }}, + { path: 'complex-table', component: _import('table/complexTable'), name: 'complexTable', meta: { title: 'complexTable' }} ] }, { - path: '/form', + path: '/example', component: Layout, - redirect: 'noredirect', - name: 'form', + redirect: '/example/list', + name: 'example', meta: { - title: 'form', - icon: 'form' + title: 'example', + icon: 'example' }, children: [ - { path: 'create-form', component: _import('form/create'), name: 'createForm', meta: { title: 'createForm', icon: 'table' }}, - { path: 'edit-form', component: _import('form/edit'), name: 'editForm', meta: { title: 'editForm', icon: 'table' }} + { path: 'create', component: _import('example/create'), name: 'createArticle', meta: { title: 'createArticle', icon: 'edit' }}, + { path: 'edit/:id(\\d+)', component: _import('example/edit'), name: 'editArticle', meta: { title: 'editArticle', noCache: true }, hidden: true }, + { path: 'list', component: _import('example/list'), name: 'articleList', meta: { title: 'articleList', icon: 'list' }} ] }, diff --git a/src/utils/index.js b/src/utils/index.js index 285cd19a..431fda2d 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -261,3 +261,7 @@ export function deepClone(source) { }) return targetObj } + +export function uniqueArr(arr) { + return Array.from(new Set(arr)) +} diff --git a/src/views/form/components/ArticleDetail.vue b/src/views/example/components/ArticleDetail.vue similarity index 52% rename from src/views/form/components/ArticleDetail.vue rename to src/views/example/components/ArticleDetail.vue index ce9dc03d..8528db44 100644 --- a/src/views/form/components/ArticleDetail.vue +++ b/src/views/example/components/ArticleDetail.vue @@ -3,100 +3,51 @@ <el-form class="form-container" :model="postForm" :rules="rules" ref="postForm"> <sticky :className="'sub-navbar '+postForm.status"> - <template v-if="fetchSuccess"> - - <router-link style="margin-right:15px;" v-show='isEdit' :to="{ path:'create-form'}"> - <el-button type="info">创建form</el-button> - </router-link> - - <el-dropdown trigger="click"> - <el-button plain>{{!postForm.comment_disabled?'评论已打开':'评论已关é—'}} - <i class="el-icon-caret-bottom el-icon--right"></i> - </el-button> - <el-dropdown-menu class="no-padding" slot="dropdown"> - <el-dropdown-item> - <el-radio-group style="padding: 10px;" v-model="postForm.comment_disabled"> - <el-radio :label="true">å…³é—评论</el-radio> - <el-radio :label="false">打开评论</el-radio> - </el-radio-group> - </el-dropdown-item> - </el-dropdown-menu> - </el-dropdown> - - <el-dropdown trigger="click"> - <el-button plain>å¹³å° - <i class="el-icon-caret-bottom el-icon--right"></i> - </el-button> - <el-dropdown-menu class="no-border" slot="dropdown"> - <el-checkbox-group v-model="postForm.platforms" style="padding: 5px 15px;"> - <el-checkbox v-for="item in platformsOptions" :label="item.key" :key="item.key"> - {{item.name}} - </el-checkbox> - </el-checkbox-group> - </el-dropdown-menu> - </el-dropdown> - - <el-dropdown trigger="click"> - <el-button plain> - 外链 - <i class="el-icon-caret-bottom el-icon--right"></i> - </el-button> - <el-dropdown-menu class="no-padding no-border" style="width:300px" slot="dropdown"> - <el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri"> - <el-input placeholder="请输入内容" v-model="postForm.source_uri"> - <template slot="prepend">填写url</template> - </el-input> - </el-form-item> - </el-dropdown-menu> - </el-dropdown> - - <el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm()">å‘布 - </el-button> - <el-button v-loading="loading" type="warning" @click="draftForm">è‰ç¨¿</el-button> - - </template> - <template v-else> - <el-tag>å‘é€å¼‚常错误,刷新页é¢,或者è”系程åºå‘˜</el-tag> - </template> - + <CommentDropdown v-model="postForm.comment_disabled" /> + <PlatformDropdown v-model="postForm.platforms" /> + <SourceUrlDropdown v-model="postForm.source_uri" /> + <el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">å‘布 + </el-button> + <el-button v-loading="loading" type="warning" @click="draftForm">è‰ç¨¿</el-button> </sticky> <div class="createPost-main-container"> <el-row> + + <Warning /> + <el-col :span="21"> <el-form-item style="margin-bottom: 40px;" prop="title"> <MDinput name="name" v-model="postForm.title" required :maxlength="100"> æ ‡é¢˜ </MDinput> - <span v-show="postForm.title.length>=26" class='title-prompt'>appå¯èƒ½ä¼šæ˜¾ç¤ºä¸å…¨</span> </el-form-item> <div class="postInfo-container"> <el-row> <el-col :span="8"> <el-form-item label-width="45px" label="作者:" class="postInfo-container-item"> - <multiselect v-model="postForm.author" :options="userLIstOptions" @search-change="getRemoteUserList" placeholder="æœç´¢ç”¨æˆ·" selectLabel="选择" - deselectLabel="åˆ é™¤" track-by="key" :internalSearch="false" label="key"> - <span slot='noResult'>æ— ç»“æžœ</span> - </multiselect> + <el-select v-model="postForm.author" filterable remote placeholder="æœç´¢ç”¨æˆ·" :remote-method="getRemoteUserList"> + <el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item"> + </el-option> + </el-select> </el-form-item> </el-col> - <el-col :span="8"> - <el-tooltip class="item" effect="dark" content="将替æ¢ä½œè€…" placement="top"> - <el-form-item label-width="50px" label="æ¥æº:" class="postInfo-container-item"> - <el-input placeholder="将替æ¢ä½œè€…" style='min-width:150px;' v-model="postForm.source_name"> - </el-input> - </el-form-item> - </el-tooltip> - </el-col> - <el-col :span="8"> <el-form-item label-width="80px" label="å‘布时间:" class="postInfo-container-item"> <el-date-picker v-model="postForm.display_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间"> </el-date-picker> </el-form-item> </el-col> + + <el-col :span="8"> + <el-form-item label-width="60px" label="é‡è¦æ€§:" class="postInfo-container-item"> + <el-rate style="margin-top:8px;" v-model="postForm.importance" :max='3' :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :low-threshold="1" + :high-threshold="3"> + </el-rate> + </el-form-item> + </el-col> </el-row> </div> </el-col> @@ -109,11 +60,11 @@ </el-form-item> <div class="editor-container"> - <tinymce :height=400 ref="editor" v-model="postForm.content"></tinymce> + <Tinymce :height=400 ref="editor" v-model="postForm.content" /> </div> <div style="margin-bottom: 20px;"> - <Upload v-model="postForm.image_uri"></Upload> + <Upload v-model="postForm.image_uri" /> </div> </div> </el-form> @@ -131,6 +82,8 @@ import Sticky from '@/components/Sticky' // 粘性header组件 import { validateURL } from '@/utils/validate' import { fetchArticle } from '@/api/article' import { userSearch } from '@/api/remoteSearch' +import Warning from './Warning' +import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown' const defaultForm = { status: 'draft', @@ -139,16 +92,16 @@ const defaultForm = { content_short: '', // æ–‡ç« æ‘˜è¦ source_uri: '', // æ–‡ç« å¤–é“¾ image_uri: '', // æ–‡ç« å›¾ç‰‡ - source_name: '', // æ–‡ç« å¤–éƒ¨ä½œè€… display_time: undefined, // å‰å°å±•ç¤ºæ—¶é—´ id: undefined, platforms: ['a-platform'], - comment_disabled: false + comment_disabled: false, + importance: 0 } export default { name: 'articleDetail', - components: { Tinymce, MDinput, Upload, Multiselect, Sticky }, + components: { Tinymce, MDinput, Upload, Multiselect, Sticky, Warning, CommentDropdown, PlatformDropdown, SourceUrlDropdown }, props: { isEdit: { type: Boolean, @@ -184,14 +137,8 @@ export default { } return { postForm: Object.assign({}, defaultForm), - fetchSuccess: true, loading: false, - userLIstOptions: [], - platformsOptions: [ - { key: 'a-platform', name: 'a-platform' }, - { key: 'b-platform', name: 'b-platform' }, - { key: 'c-platform', name: 'c-platform' } - ], + userListOptions: [], rules: { image_uri: [{ validator: validateRequire }], title: [{ validator: validateRequire }], @@ -207,17 +154,20 @@ export default { }, created() { if (this.isEdit) { - this.fetchData() + const id = this.$route.params && this.$route.params.id + this.fetchData(id) } else { this.postForm = Object.assign({}, defaultForm) } }, methods: { - fetchData() { - fetchArticle().then(response => { + fetchData(id) { + fetchArticle(id).then(response => { this.postForm = response.data + // Just for test + this.postForm.title += ` Article Id:${this.postForm.id}` + this.postForm.content_short += ` Article Id:${this.postForm.id}` }).catch(err => { - this.fetchSuccess = false console.log(err) }) }, @@ -260,10 +210,7 @@ export default { getRemoteUserList(query) { userSearch(query).then(response => { if (!response.data.items) return - console.log(response) - this.userLIstOptions = response.data.items.map(v => ({ - key: v.name - })) + this.userListOptions = response.data.items.map(v => v.name) }) } } @@ -271,44 +218,36 @@ export default { </script> <style rel="stylesheet/scss" lang="scss" scoped> - @import "src/styles/mixin.scss"; - .title-prompt{ - position: absolute; - right: 0px; - font-size: 12px; - top:10px; - color:#ff4949; - } - .createPost-container { - position: relative; - .createPost-main-container { - padding: 40px 45px 20px 50px; - .postInfo-container { - position: relative; - @include clearfix; - margin-bottom: 10px; - .postInfo-container-item { - float: left; - } +@import "src/styles/mixin.scss"; +.createPost-container { + position: relative; + .createPost-main-container { + padding: 40px 45px 20px 50px; + .postInfo-container { + position: relative; + @include clearfix; + margin-bottom: 10px; + .postInfo-container-item { + float: left; } - .editor-container { - min-height: 500px; - margin: 0 0 30px; - .editor-upload-btn-container { - text-align: right; - margin-right: 10px; - .editor-upload-btn { - display: inline-block; - } + } + .editor-container { + min-height: 500px; + margin: 0 0 30px; + .editor-upload-btn-container { + text-align: right; + margin-right: 10px; + .editor-upload-btn { + display: inline-block; } } } - .word-counter { - width: 40px; - position: absolute; - right: -10px; - top: 0px; - } } + .word-counter { + width: 40px; + position: absolute; + right: -10px; + top: 0px; + } +} </style> - diff --git a/src/views/example/components/Dropdown/Comment.vue b/src/views/example/components/Dropdown/Comment.vue new file mode 100644 index 00000000..da217599 --- /dev/null +++ b/src/views/example/components/Dropdown/Comment.vue @@ -0,0 +1,31 @@ +<template> + <el-dropdown trigger="click" :show-timeout="100"> + <el-button plain>{{!comment_disabled?'评论已打开':'评论已关é—'}} + <i class="el-icon-caret-bottom el-icon--right"></i> + </el-button> + <el-dropdown-menu class="no-padding" slot="dropdown"> + <el-dropdown-item> + <el-radio-group style="padding: 10px;" v-model="comment_disabled"> + <el-radio :label="true">å…³é—评论</el-radio> + <el-radio :label="false">打开评论</el-radio> + </el-radio-group> + </el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> +</template> + +<script> +export default { + props: ['value'], + computed: { + comment_disabled: { + get() { + return this.value + }, + set(val) { + this.$emit('input', val) + } + } + } +} +</script> diff --git a/src/views/example/components/Dropdown/Platform.vue b/src/views/example/components/Dropdown/Platform.vue new file mode 100644 index 00000000..a20321dd --- /dev/null +++ b/src/views/example/components/Dropdown/Platform.vue @@ -0,0 +1,40 @@ +<template> + <el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click"> + <el-button plain> + å¹³å°({{platforms.length}}) + <i class="el-icon-caret-bottom el-icon--right"></i> + </el-button> + <el-dropdown-menu class="no-border" slot="dropdown"> + <el-checkbox-group v-model="platforms" style="padding: 5px 15px;"> + <el-checkbox v-for="item in platformsOptions" :label="item.key" :key="item.key"> + {{item.name}} + </el-checkbox> + </el-checkbox-group> + </el-dropdown-menu> + </el-dropdown> +</template> + +<script> +export default { + props: ['value'], + data() { + return { + platformsOptions: [ + { key: 'a-platform', name: 'a-platform' }, + { key: 'b-platform', name: 'b-platform' }, + { key: 'c-platform', name: 'c-platform' } + ] + } + }, + computed: { + platforms: { + get() { + return this.value + }, + set(val) { + this.$emit('input', val) + } + } + } +} +</script> diff --git a/src/views/example/components/Dropdown/SourceUrl.vue b/src/views/example/components/Dropdown/SourceUrl.vue new file mode 100644 index 00000000..f09eb69d --- /dev/null +++ b/src/views/example/components/Dropdown/SourceUrl.vue @@ -0,0 +1,31 @@ +<template> + <el-dropdown :show-timeout="100" trigger="click"> + <el-button plain> + 外链 + <i class="el-icon-caret-bottom el-icon--right"></i> + </el-button> + <el-dropdown-menu class="no-padding no-border" style="width:400px" slot="dropdown"> + <el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri"> + <el-input placeholder="请输入内容" v-model="source_uri"> + <template slot="prepend">填写url</template> + </el-input> + </el-form-item> + </el-dropdown-menu> + </el-dropdown> +</template> + +<script> +export default { + props: ['value'], + computed: { + source_uri: { + get() { + return this.value + }, + set(val) { + this.$emit('input', val) + } + } + } +} +</script> diff --git a/src/views/example/components/Dropdown/index.js b/src/views/example/components/Dropdown/index.js new file mode 100644 index 00000000..bc0c171b --- /dev/null +++ b/src/views/example/components/Dropdown/index.js @@ -0,0 +1,3 @@ +export { default as CommentDropdown } from './Comment' +export { default as PlatformDropdown } from './Platform' +export { default as SourceUrlDropdown } from './SourceUrl' diff --git a/src/views/example/components/Warning.vue b/src/views/example/components/Warning.vue new file mode 100644 index 00000000..a0012ede --- /dev/null +++ b/src/views/example/components/Warning.vue @@ -0,0 +1,9 @@ +<template> + <p class="warn-content"> + 创建和编辑页é¢æ˜¯ä¸èƒ½è¢«keep-alive 缓å˜çš„ï¼Œå› ä¸ºkeep-alive çš„include ç›®å‰ä¸æ”¯æŒæ ¹æ®è·¯ç”±æ¥ç¼“å˜ï¼Œæ‰€ä»¥ç›®å‰éƒ½æ˜¯åŸºäºŽcomponent name æ¥ç¼“å˜çš„ï¼Œå¦‚æžœä½ æƒ³è¦å®žçŽ°ç¼“å˜çš„效果,å¯ä»¥ä½¿ç”¨localstorage ç‰æ¸¸è§ˆå™¨ç¼“å˜æ–¹æ¡ˆã€‚或者ä¸è¦ä½¿ç”¨keep-alive + çš„include,直接缓å˜æ‰€æœ‰é¡µé¢ã€‚è¯¦æƒ…è§ + <a href="https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/tags-view?id=%E7%BC%93%E5%AD%98%E4%B8%8D%E9%80%82%E5%90%88%E5%9C%BA%E6%99%AF" + target="_blank">文档</a> + </p> +</template> + diff --git a/src/views/form/create.vue b/src/views/example/create.vue similarity index 100% rename from src/views/form/create.vue rename to src/views/example/create.vue diff --git a/src/views/form/edit.vue b/src/views/example/edit.vue similarity index 100% rename from src/views/form/edit.vue rename to src/views/example/edit.vue diff --git a/src/views/example/list.vue b/src/views/example/list.vue new file mode 100644 index 00000000..7dccafa6 --- /dev/null +++ b/src/views/example/list.vue @@ -0,0 +1,121 @@ +<template> + <div class="app-container"> + + <el-table :data="list" v-loading.body="listLoading" border fit highlight-current-row style="width: 100%"> + <el-table-column align="center" label="ID" width="80"> + <template slot-scope="scope"> + <span>{{scope.row.id}}</span> + </template> + </el-table-column> + + <el-table-column width="180px" align="center" label="Date"> + <template slot-scope="scope"> + <span>{{scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}')}}</span> + </template> + </el-table-column> + + <el-table-column width="120px" align="center" label="Author"> + <template slot-scope="scope"> + <span>{{scope.row.author}}</span> + </template> + </el-table-column> + + <el-table-column width="100px" label="Importance"> + <template slot-scope="scope"> + <svg-icon v-for="n in +scope.row.importance" icon-class="star" class="meta-item__icon" :key="n"></svg-icon> + </template> + </el-table-column> + + <el-table-column class-name="status-col" label="Status" width="110"> + <template slot-scope="scope"> + <el-tag :type="scope.row.status | statusFilter">{{scope.row.status}}</el-tag> + </template> + </el-table-column> + + <el-table-column min-width="300px" label="Title"> + <template slot-scope="scope"> + + <router-link class="link-type" :to="'/example/edit/'+scope.row.id"> + <span>{{ scope.row.title }}</span> + </router-link> + </template> + </el-table-column> + + <el-table-column align="center" label="Actions" width="120"> + <template slot-scope="scope"> + <router-link :to="'/example/edit/'+scope.row.id"> + <el-button type="primary" size="small" icon="el-icon-edit">Edit</el-button> + </router-link> + </template> + </el-table-column> + </el-table> + + <div class="pagination-container"> + <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.page" + :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total"> + </el-pagination> + </div> + + </div> +</template> + +<script> +import { fetchList } from '@/api/article' + +export default { + name: 'articleList', + data() { + return { + list: null, + total: 0, + listLoading: true, + listQuery: { + page: 1, + limit: 10 + } + } + }, + filters: { + statusFilter(status) { + const statusMap = { + published: 'success', + draft: 'info', + deleted: 'danger' + } + return statusMap[status] + } + }, + created() { + this.getList() + }, + methods: { + getList() { + this.listLoading = true + fetchList(this.listQuery).then(response => { + this.list = response.data.items + this.total = response.data.total + this.listLoading = false + }) + }, + handleSizeChange(val) { + this.listQuery.limit = val + this.getList() + }, + handleCurrentChange(val) { + this.listQuery.page = val + this.getList() + } + } +} +</script> + +<style scoped> +.edit-input { + padding-right: 100px; +} +.cancel-btn { + position: absolute; + right: 15px; + top: 10px; +} +</style> diff --git a/src/views/example/table/index.vue b/src/views/example/table/index.vue deleted file mode 100644 index de92c020..00000000 --- a/src/views/example/table/index.vue +++ /dev/null @@ -1,18 +0,0 @@ -<template> - <transition name="fade" mode="out-in"> - <keep-alive :include='cachedViews'> - <router-view></router-view> - </keep-alive> - </transition> -</template> - -<script> -export default { - name: 'TableMain', - computed: { - cachedViews() { - return this.$store.state.tagsView.cachedViews - } - } -} -</script> diff --git a/src/views/layout/components/AppMain.vue b/src/views/layout/components/AppMain.vue index 8e10a9e5..770ab432 100644 --- a/src/views/layout/components/AppMain.vue +++ b/src/views/layout/components/AppMain.vue @@ -2,7 +2,7 @@ <section class="app-main" style="min-height: 100%"> <transition name="fade-transform" mode="out-in"> <keep-alive :include="cachedViews"> - <router-view></router-view> + <router-view :key="key"></router-view> </keep-alive> </transition> </section> @@ -14,10 +14,10 @@ export default { computed: { cachedViews() { return this.$store.state.tagsView.cachedViews + }, + key() { + return this.$route.fullPath } - // key() { - // return this.$route.name !== undefined ? this.$route.name + +new Date() : this.$route + +new Date() - // } } } </script> diff --git a/src/views/layout/components/TagsView.vue b/src/views/layout/components/TagsView.vue index c3199338..55467fc9 100644 --- a/src/views/layout/components/TagsView.vue +++ b/src/views/layout/components/TagsView.vue @@ -59,7 +59,7 @@ export default { return false }, isActive(route) { - return route.path === this.$route.path || route.name === this.$route.name + return route.path === this.$route.path }, addViewTags() { const route = this.generateRoute() diff --git a/src/views/example/tab/components/tabPane.vue b/src/views/tab/components/tabPane.vue similarity index 100% rename from src/views/example/tab/components/tabPane.vue rename to src/views/tab/components/tabPane.vue diff --git a/src/views/example/tab/index.vue b/src/views/tab/index.vue similarity index 85% rename from src/views/example/tab/index.vue rename to src/views/tab/index.vue index 2a3239a3..7f4b9bfa 100644 --- a/src/views/example/tab/index.vue +++ b/src/views/tab/index.vue @@ -1,6 +1,8 @@ <template> <div class="tab-container"> <el-tag>mounted times :{{createdTimes}}</el-tag> + <el-alert style="width:200px;display:inline-block;vertical-align: middle;margin-left:30px;" title="Tab with keep-alive" type="success" :closable="false"> + </el-alert> <el-tabs style='margin-top:15px;' v-model="activeName" type="border-card"> <el-tab-pane v-for="item in tabMapOptions" :label="item.label" :key='item.key' :name="item.key"> <keep-alive> diff --git a/src/views/example/table/complexTable.vue b/src/views/table/complexTable.vue similarity index 99% rename from src/views/example/table/complexTable.vue rename to src/views/table/complexTable.vue index a5442ce1..f6171c5f 100644 --- a/src/views/example/table/complexTable.vue +++ b/src/views/table/complexTable.vue @@ -1,5 +1,5 @@ <template> - <div class="app-container calendar-list-container"> + <div class="app-container"> <div class="filter-container"> <el-input @keyup.enter.native="handleFilter" style="width: 200px;" class="filter-item" :placeholder="$t('table.title')" v-model="listQuery.title"> </el-input> diff --git a/src/views/example/table/dragTable.vue b/src/views/table/dragTable.vue similarity index 98% rename from src/views/example/table/dragTable.vue rename to src/views/table/dragTable.vue index 9e411e64..f13dcb32 100644 --- a/src/views/example/table/dragTable.vue +++ b/src/views/table/dragTable.vue @@ -1,5 +1,5 @@ <template> - <div class="app-container calendar-list-container"> + <div class="app-container"> <!-- Note that row-key is necessary to get a correct row order. --> <el-table :data="list" row-key="id" v-loading.body="listLoading" border fit highlight-current-row style="width: 100%"> diff --git a/src/views/example/table/dynamicTable/fixedThead.vue b/src/views/table/dynamicTable/fixedThead.vue similarity index 100% rename from src/views/example/table/dynamicTable/fixedThead.vue rename to src/views/table/dynamicTable/fixedThead.vue diff --git a/src/views/example/table/dynamicTable/index.vue b/src/views/table/dynamicTable/index.vue similarity index 100% rename from src/views/example/table/dynamicTable/index.vue rename to src/views/table/dynamicTable/index.vue diff --git a/src/views/example/table/dynamicTable/unfixedThead.vue b/src/views/table/dynamicTable/unfixedThead.vue similarity index 100% rename from src/views/example/table/dynamicTable/unfixedThead.vue rename to src/views/table/dynamicTable/unfixedThead.vue diff --git a/src/views/example/table/inlineEditTable.vue b/src/views/table/inlineEditTable.vue similarity index 98% rename from src/views/example/table/inlineEditTable.vue rename to src/views/table/inlineEditTable.vue index 3d2ad00f..c44efccc 100644 --- a/src/views/example/table/inlineEditTable.vue +++ b/src/views/table/inlineEditTable.vue @@ -1,5 +1,5 @@ <template> - <div class="app-container calendar-list-container"> + <div class="app-container"> <el-table :data="list" v-loading.body="listLoading" border fit highlight-current-row style="width: 100%"> diff --git a/src/views/example/table/treeTable/customEval.js b/src/views/table/treeTable/customEval.js similarity index 100% rename from src/views/example/table/treeTable/customEval.js rename to src/views/table/treeTable/customEval.js diff --git a/src/views/example/table/treeTable/customTreeTable.vue b/src/views/table/treeTable/customTreeTable.vue similarity index 100% rename from src/views/example/table/treeTable/customTreeTable.vue rename to src/views/table/treeTable/customTreeTable.vue diff --git a/src/views/example/table/treeTable/treeTable.vue b/src/views/table/treeTable/treeTable.vue similarity index 100% rename from src/views/example/table/treeTable/treeTable.vue rename to src/views/table/treeTable/treeTable.vue -- GitLab