-
+
@@ -13,11 +13,14 @@ import plugins from './plugins'
import toolbar from './toolbar'
export default {
- name: 'tinymce',
+ name: 'Tinymce',
components: { editorImage },
props: {
id: {
- type: String
+ type: String,
+ default: function() {
+ return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
+ }
},
value: {
type: String,
@@ -31,6 +34,7 @@ export default {
}
},
menubar: {
+ type: String,
default: 'file edit insert view format table'
},
height: {
@@ -43,14 +47,29 @@ export default {
return {
hasChange: false,
hasInit: false,
- tinymceId: this.id || 'vue-tinymce-' + +new Date()
+ tinymceId: this.id,
+ fullscreen: false,
+ languageTypeList: {
+ 'en': 'en',
+ 'zh': 'zh_CN'
+ }
+ }
+ },
+ computed: {
+ language() {
+ return this.languageTypeList[this.$store.getters.language]
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
- this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val))
+ this.$nextTick(() =>
+ window.tinymce.get(this.tinymceId).setContent(val || ''))
}
+ },
+ language() {
+ this.destroyTinymce()
+ this.$nextTick(() => this.initTinymce())
}
},
mounted() {
@@ -62,10 +81,14 @@ export default {
deactivated() {
this.destroyTinymce()
},
+ destroyed() {
+ this.destroyTinymce()
+ },
methods: {
initTinymce() {
const _this = this
window.tinymce.init({
+ language: this.language,
selector: `#${this.tinymceId}`,
height: this.height,
body_class: 'panel-body ',
@@ -82,6 +105,7 @@ export default {
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
link_title: false,
+ nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
@@ -91,6 +115,11 @@ export default {
this.hasChange = true
this.$emit('input', editor.getContent())
})
+ },
+ setup(editor) {
+ editor.on('FullscreenStateChanged', (e) => {
+ _this.fullscreen = e.state
+ })
}
// 整合七牛上传
// images_dataimg_filter(img) {
@@ -144,16 +173,16 @@ export default {
window.tinymce.get(_this.tinymceId).insertContent(`
`)
})
}
- },
- destroyed() {
- this.destroyTinymce()
}
}
diff --git a/src/components/Upload/singleImage3.vue b/src/components/Upload/singleImage3.vue
index ea63e648..637b9e1e 100644
--- a/src/components/Upload/singleImage3.vue
+++ b/src/components/Upload/singleImage3.vue
@@ -1,40 +1,44 @@
-
-
-
- 将文件拖到此处,或点击上传
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ 将文件拖到此处,或点击上传
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/bug.svg b/src/icons/svg/bug.svg
index a12a9394..05a150dc 100644
--- a/src/icons/svg/bug.svg
+++ b/src/icons/svg/bug.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/chart.svg b/src/icons/svg/chart.svg
index b1b31336..27728fb0 100644
--- a/src/icons/svg/chart.svg
+++ b/src/icons/svg/chart.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/clipboard.svg b/src/icons/svg/clipboard.svg
index cf1c9b0c..90923ff6 100644
--- a/src/icons/svg/clipboard.svg
+++ b/src/icons/svg/clipboard.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/component.svg b/src/icons/svg/component.svg
index a8008c84..207ada34 100644
--- a/src/icons/svg/component.svg
+++ b/src/icons/svg/component.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/dashboard.svg b/src/icons/svg/dashboard.svg
index bee42507..5317d370 100644
--- a/src/icons/svg/dashboard.svg
+++ b/src/icons/svg/dashboard.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/documentation.svg b/src/icons/svg/documentation.svg
index 405c2ad7..70431228 100644
--- a/src/icons/svg/documentation.svg
+++ b/src/icons/svg/documentation.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/drag.svg b/src/icons/svg/drag.svg
index 819c8d50..4185d3ce 100644
--- a/src/icons/svg/drag.svg
+++ b/src/icons/svg/drag.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/edit.svg b/src/icons/svg/edit.svg
new file mode 100644
index 00000000..0306a867
--- /dev/null
+++ b/src/icons/svg/edit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/email.svg b/src/icons/svg/email.svg
index 8a87e147..055e5013 100644
--- a/src/icons/svg/email.svg
+++ b/src/icons/svg/email.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/example.svg b/src/icons/svg/example.svg
index 681422ea..46f42b53 100644
--- a/src/icons/svg/example.svg
+++ b/src/icons/svg/example.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/excel.svg b/src/icons/svg/excel.svg
index e5dd5cec..59d54b2c 100644
--- a/src/icons/svg/excel.svg
+++ b/src/icons/svg/excel.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/eye.svg b/src/icons/svg/eye.svg
index 194aa45c..16ed2d87 100644
--- a/src/icons/svg/eye.svg
+++ b/src/icons/svg/eye.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/form.svg b/src/icons/svg/form.svg
index 79716f06..dcbaa185 100644
--- a/src/icons/svg/form.svg
+++ b/src/icons/svg/form.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/guide 2.svg b/src/icons/svg/guide 2.svg
new file mode 100644
index 00000000..d053bd73
--- /dev/null
+++ b/src/icons/svg/guide 2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/guide.svg b/src/icons/svg/guide.svg
new file mode 100644
index 00000000..b2710017
--- /dev/null
+++ b/src/icons/svg/guide.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/icon.svg b/src/icons/svg/icon.svg
index 906af96a..82be8eee 100644
--- a/src/icons/svg/icon.svg
+++ b/src/icons/svg/icon.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/international.svg b/src/icons/svg/international.svg
index 6912767d..e9b56eee 100644
--- a/src/icons/svg/international.svg
+++ b/src/icons/svg/international.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/language.svg b/src/icons/svg/language.svg
index 2baf7431..96d00288 100644
--- a/src/icons/svg/language.svg
+++ b/src/icons/svg/language.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/src/icons/svg/link.svg b/src/icons/svg/link.svg
new file mode 100644
index 00000000..07090147
--- /dev/null
+++ b/src/icons/svg/link.svg
@@ -0,0 +1 @@
+
\ 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..20259edd
--- /dev/null
+++ b/src/icons/svg/list.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/lock.svg b/src/icons/svg/lock.svg
index 37c60701..74fee543 100644
--- a/src/icons/svg/lock.svg
+++ b/src/icons/svg/lock.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/message.svg b/src/icons/svg/message.svg
index d807b002..14ca8172 100644
--- a/src/icons/svg/message.svg
+++ b/src/icons/svg/message.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/money.svg b/src/icons/svg/money.svg
index d4fcb9ca..c1580de1 100644
--- a/src/icons/svg/money.svg
+++ b/src/icons/svg/money.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/nested.svg b/src/icons/svg/nested.svg
new file mode 100644
index 00000000..06713a86
--- /dev/null
+++ b/src/icons/svg/nested.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/password.svg b/src/icons/svg/password.svg
index 920b500b..e291d85d 100644
--- a/src/icons/svg/password.svg
+++ b/src/icons/svg/password.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/people.svg b/src/icons/svg/people.svg
index 3985ab51..2bd54aeb 100644
--- a/src/icons/svg/people.svg
+++ b/src/icons/svg/people.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/peoples.svg b/src/icons/svg/peoples.svg
index 2dccfcc0..2c911615 100644
--- a/src/icons/svg/peoples.svg
+++ b/src/icons/svg/peoples.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/qq.svg b/src/icons/svg/qq.svg
index 97aee717..ee13d4ec 100644
--- a/src/icons/svg/qq.svg
+++ b/src/icons/svg/qq.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/shopping.svg b/src/icons/svg/shopping.svg
new file mode 100644
index 00000000..87513e7c
--- /dev/null
+++ b/src/icons/svg/shopping.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/shoppingCard.svg b/src/icons/svg/shoppingCard.svg
deleted file mode 100644
index cdebbdb4..00000000
--- a/src/icons/svg/shoppingCard.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/svg/size.svg b/src/icons/svg/size.svg
new file mode 100644
index 00000000..ddb25b8d
--- /dev/null
+++ b/src/icons/svg/size.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/star.svg b/src/icons/svg/star.svg
index 685a301d..6cf86e66 100644
--- a/src/icons/svg/star.svg
+++ b/src/icons/svg/star.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/tab.svg b/src/icons/svg/tab.svg
index 17aa088b..b4b48e48 100644
--- a/src/icons/svg/tab.svg
+++ b/src/icons/svg/tab.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/table.svg b/src/icons/svg/table.svg
index 083bc8cc..dbfe5d64 100644
--- a/src/icons/svg/table.svg
+++ b/src/icons/svg/table.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/theme.svg b/src/icons/svg/theme.svg
index d5c2e5ad..5982a2f7 100644
--- a/src/icons/svg/theme.svg
+++ b/src/icons/svg/theme.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/src/icons/svg/tree.svg b/src/icons/svg/tree.svg
new file mode 100644
index 00000000..dd4b7dd2
--- /dev/null
+++ b/src/icons/svg/tree.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/icons/svg/user.svg b/src/icons/svg/user.svg
index 5971deeb..0ba0716a 100644
--- a/src/icons/svg/user.svg
+++ b/src/icons/svg/user.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/wechat.svg b/src/icons/svg/wechat.svg
index d88a64bc..9e18b717 100644
--- a/src/icons/svg/wechat.svg
+++ b/src/icons/svg/wechat.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/icons/svg/zip.svg b/src/icons/svg/zip.svg
index e9a9d012..f806fc48 100644
--- a/src/icons/svg/zip.svg
+++ b/src/icons/svg/zip.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/src/icons/svgo.yml b/src/icons/svgo.yml
new file mode 100644
index 00000000..d11906ae
--- /dev/null
+++ b/src/icons/svgo.yml
@@ -0,0 +1,22 @@
+# replace default config
+
+# multipass: true
+# full: true
+
+plugins:
+
+ # - name
+ #
+ # or:
+ # - name: false
+ # - name: true
+ #
+ # or:
+ # - name:
+ # param1: 1
+ # param2: 2
+
+- removeAttrs:
+ attrs:
+ - 'fill'
+ - 'fill-rule'
diff --git a/src/lang/en.js b/src/lang/en.js
index 30fe5b34..021bc66c 100644
--- a/src/lang/en.js
+++ b/src/lang/en.js
@@ -3,7 +3,10 @@ export default {
dashboard: 'Dashboard',
introduction: 'Introduction',
documentation: 'Documentation',
+ guide: 'Guide',
permission: 'Permission',
+ pagePermission: 'Page Permission',
+ directivePermission: 'Directive Permission',
icons: 'Icons',
components: 'Components',
componentIndex: 'Introduction',
@@ -18,11 +21,21 @@ export default {
countTo: 'CountTo',
componentMixin: 'Mixin',
backToTop: 'BackToTop',
+ dragDialog: 'Drag Dialog',
+ dragKanban: 'Drag Kanban',
charts: 'Charts',
keyboardChart: 'Keyboard Chart',
lineChart: 'Line Chart',
mixChart: 'Mix Chart',
example: 'Example',
+ nested: 'Nested Routes',
+ menu1: 'Menu 1',
+ 'menu1-1': 'Menu 1-1',
+ 'menu1-2': 'Menu 1-2',
+ 'menu1-2-1': 'Menu 1-2-1',
+ 'menu1-2-2': 'Menu 1-2-2',
+ 'menu1-3': 'Menu 1-3',
+ menu2: 'Menu 2',
Table: 'Table',
dynamicTable: 'Dynamic Table',
dragTable: 'Drag Table',
@@ -32,8 +45,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',
@@ -46,14 +60,16 @@ export default {
exportZip: 'Export Zip',
theme: 'Theme',
clipboardDemo: 'Clipboard',
- i18n: 'I18n'
+ i18n: 'I18n',
+ externalLink: 'External Link'
},
navbar: {
logOut: 'Log Out',
dashboard: 'Dashboard',
github: 'Github',
- screenfull: 'screenfull',
- theme: 'theme'
+ screenfull: 'Screenfull',
+ theme: 'Theme',
+ size: 'Global Size'
},
login: {
title: 'Login Form',
@@ -72,6 +88,10 @@ export default {
roles: 'Your roles',
switchRoles: 'Switch roles'
},
+ guide: {
+ description: 'The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ',
+ button: 'Show Guide'
+ },
components: {
documentation: 'Documentation',
tinymceTips: 'Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.',
@@ -114,7 +134,7 @@ export default {
},
excel: {
export: 'Export',
- selectedExport: 'Export selected items',
+ selectedExport: 'Export Selected Items',
placeholder: 'Please enter the file name(default excel-list)'
},
zip: {
@@ -122,8 +142,14 @@ export default {
placeholder: 'Please enter the file name(default file)'
},
theme: {
- change: 'Theme change',
+ change: 'Change Theme',
documentation: 'Theme documentation',
tips: 'Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.'
+ },
+ tagsView: {
+ refresh: 'Refresh',
+ close: 'Close',
+ closeOthers: 'Close Others',
+ closeAll: 'Close All'
}
}
diff --git a/src/lang/index.js b/src/lang/index.js
index a36a9804..a77b07ea 100644
--- a/src/lang/index.js
+++ b/src/lang/index.js
@@ -20,8 +20,11 @@ const messages = {
}
const i18n = new VueI18n({
- locale: Cookies.get('language') || 'en', // set locale
- messages // set locale messages
+ // set locale
+ // options: en or zh
+ locale: Cookies.get('language') || 'en',
+ // set locale messages
+ messages
})
export default i18n
diff --git a/src/lang/zh.js b/src/lang/zh.js
index 4c1e3ac2..9da9e9e4 100644
--- a/src/lang/zh.js
+++ b/src/lang/zh.js
@@ -3,7 +3,10 @@ export default {
dashboard: '首页',
introduction: '简述',
documentation: '文档',
+ guide: '引导页',
permission: '权限测试页',
+ pagePermission: '页面权限',
+ directivePermission: '指令权限',
icons: '图标',
components: '组件',
componentIndex: '介绍',
@@ -18,11 +21,21 @@ export default {
countTo: 'CountTo',
componentMixin: '小组件',
backToTop: '返回顶部',
+ dragDialog: '拖拽 Dialog',
+ dragKanban: '可拖拽看板',
charts: '图表',
keyboardChart: '键盘图表',
lineChart: '折线图',
mixChart: '混合图表',
example: '综合实例',
+ nested: '路由嵌套',
+ menu1: '菜单1',
+ 'menu1-1': '菜单1-1',
+ 'menu1-2': '菜单1-2',
+ 'menu1-2-1': '菜单1-2-1',
+ 'menu1-2-2': '菜单1-2-2',
+ 'menu1-3': '菜单1-3',
+ menu2: '菜单2',
Table: 'Table',
dynamicTable: '动态Table',
dragTable: '拖拽Table',
@@ -32,8 +45,9 @@ export default {
customTreeTable: '自定义树表',
tab: 'Tab',
form: '表单',
- createForm: '创建表单',
- editForm: '编辑表单',
+ createArticle: '创建文章',
+ editArticle: '编辑文章',
+ articleList: '文章列表',
errorPages: '错误页面',
page401: '401',
page404: '404',
@@ -46,14 +60,16 @@ export default {
exportZip: 'Export Zip',
theme: '换肤',
clipboardDemo: 'Clipboard',
- i18n: '国际化'
+ i18n: '国际化',
+ externalLink: '外链'
},
navbar: {
logOut: '退出登录',
dashboard: '首页',
github: '项目地址',
screenfull: '全屏',
- theme: '换肤'
+ theme: '换肤',
+ size: '布局大小'
},
login: {
title: '系统登录',
@@ -72,6 +88,10 @@ export default {
roles: '你的权限',
switchRoles: '切换权限'
},
+ guide: {
+ description: '引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。本 Demo 是基于',
+ button: '打开引导'
+ },
components: {
documentation: '文档',
tinymceTips: '富文本是管理后台一个核心的功能,但同时又是一个有很多坑的地方。在选择富文本的过程中我也走了不少的弯路,市面上常见的富文本都基本用过了,最终权衡了一下选择了Tinymce。更详细的富文本比较和介绍见',
@@ -125,5 +145,11 @@ export default {
change: '换肤',
documentation: '换肤文档',
tips: 'Tips: 它区别于 navbar 上的 theme-pick, 是两种不同的换肤方法,各自有不同的应用场景,具体请参考文档。'
+ },
+ tagsView: {
+ refresh: '刷新',
+ close: '关闭',
+ closeOthers: '关闭其它',
+ closeAll: '关闭所有'
}
}
diff --git a/src/main.js b/src/main.js
index 07cbbe6e..1ce709c9 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,6 +1,8 @@
import Vue from 'vue'
-import 'normalize.css/normalize.css'// A modern alternative to CSS resets
+import Cookies from 'js-cookie'
+
+import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
@@ -13,14 +15,14 @@ import store from './store'
import i18n from './lang' // Internationalization
import './icons' // icon
-import './errorLog'// error log
+import './errorLog' // error log
import './permission' // permission control
import './mock' // simulation data
import * as filters from './filters' // global filters
Vue.use(Element, {
- size: 'medium', // set element-ui default size
+ size: Cookies.get('size') || 'medium', // set element-ui default size
i18n: (key, value) => i18n.t(key, value)
})
@@ -36,6 +38,5 @@ new Vue({
router,
store,
i18n,
- template: '
',
- components: { App }
+ render: h => h(App)
})
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 = '
我是测试数据我是测试数据
'
+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: '
我是测试数据我是测试数据
"',
- 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/permission.js b/src/permission.js
index 87a591e5..81f9d113 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -7,14 +7,14 @@ import { getToken } from '@/utils/auth' // getToken from cookie
NProgress.configure({ showSpinner: false })// NProgress Configuration
-// permissiom judge function
+// permission judge function
function hasPermission(roles, permissionRoles) {
if (roles.indexOf('admin') >= 0) return true // admin permission passed directly
if (!permissionRoles) return true
return roles.some(role => permissionRoles.indexOf(role) >= 0)
}
-const whiteList = ['/login', '/authredirect']// no redirect whitelist
+const whiteList = ['/login', '/auth-redirect']// no redirect whitelist
router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar
@@ -31,16 +31,16 @@ router.beforeEach((to, from, next) => {
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
})
- }).catch(() => {
+ }).catch((err) => {
store.dispatch('FedLogOut').then(() => {
- Message.error('Verification failed, please login again')
- next({ path: '/login' })
+ Message.error(err || 'Verification failed, please login again')
+ next({ path: '/' })
})
})
} else {
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
if (hasPermission(store.getters.roles, to.meta.roles)) {
- next()//
+ next()
} else {
next({ path: '/401', replace: true, query: { noGoBack: true }})
}
@@ -52,7 +52,7 @@ router.beforeEach((to, from, next) => {
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next()
} else {
- next('/login') // 否则全部重定向到登录页
+ next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
diff --git a/src/router/_import_development.js b/src/router/_import_development.js
deleted file mode 100644
index 7c8b5e6b..00000000
--- a/src/router/_import_development.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+
diff --git a/src/router/_import_production.js b/src/router/_import_production.js
deleted file mode 100644
index 331acba4..00000000
--- a/src/router/_import_production.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = file => () => import('@/views/' + file + '.vue')
diff --git a/src/router/index.js b/src/router/index.js
index 596564b9..ab328c46 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,24 +1,27 @@
import Vue from 'vue'
import Router from 'vue-router'
-const _import = require('./_import_' + process.env.NODE_ENV)
-// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading;
-// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading
Vue.use(Router)
/* Layout */
-import Layout from '../views/layout/Layout'
+import Layout from '@/views/layout/Layout'
-/** note: submenu only apppear when children.length>=1
-* detail see https://panjiachen.github.io/vue-element-admin-site/#/router-and-nav?id=sidebar
-**/
+/* Router Modules */
+import componentsRouter from './modules/components'
+import chartsRouter from './modules/charts'
+import tableRouter from './modules/table'
+import nestedRouter from './modules/nested'
+
+/** note: Submenu only appear when children.length>=1
+ * detail see https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
+ **/
/**
* hidden: true if `hidden:true` will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu, whatever its child routes length
* if not set alwaysShow, only more than one route under the children
* it will becomes nested mode, otherwise not show the root menu
-* redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb
+* redirect: noredirect if `redirect:noredirect` will no redirect in the breadcrumb
* name:'router-name' the name is used by
(must set!!!)
* meta : {
roles: ['admin','editor'] will control the page roles (you can set multiple roles)
@@ -28,31 +31,75 @@ import Layout from '../views/layout/Layout'
}
**/
export const constantRouterMap = [
- { path: '/login', component: _import('login/index'), hidden: true },
- { path: '/authredirect', component: _import('login/authredirect'), hidden: true },
- { path: '/404', component: _import('errorPage/404'), hidden: true },
- { path: '/401', component: _import('errorPage/401'), hidden: true },
+ {
+ path: '/redirect',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: '/redirect/:path*',
+ component: () => import('@/views/redirect/index')
+ }
+ ]
+ },
+ {
+ path: '/login',
+ component: () => import('@/views/login/index'),
+ hidden: true
+ },
+ {
+ path: '/auth-redirect',
+ component: () => import('@/views/login/authredirect'),
+ hidden: true
+ },
+ {
+ path: '/404',
+ component: () => import('@/views/errorPage/404'),
+ hidden: true
+ },
+ {
+ path: '/401',
+ component: () => import('@/views/errorPage/401'),
+ hidden: true
+ },
{
path: '',
component: Layout,
redirect: 'dashboard',
- children: [{
- path: 'dashboard',
- component: _import('dashboard/index'),
- name: 'dashboard',
- meta: { title: 'dashboard', icon: 'dashboard', noCache: true }
- }]
+ children: [
+ {
+ path: 'dashboard',
+ component: () => import('@/views/dashboard/index'),
+ name: 'Dashboard',
+ meta: { title: 'dashboard', icon: 'dashboard', noCache: true }
+ }
+ ]
},
{
path: '/documentation',
component: Layout,
redirect: '/documentation/index',
- children: [{
- path: 'index',
- component: _import('documentation/index'),
- name: 'documentation',
- meta: { title: 'documentation', icon: 'documentation', noCache: true }
- }]
+ children: [
+ {
+ path: 'index',
+ component: () => import('@/views/documentation/index'),
+ name: 'Documentation',
+ meta: { title: 'documentation', icon: 'documentation', noCache: true }
+ }
+ ]
+ },
+ {
+ path: '/guide',
+ component: Layout,
+ redirect: '/guide/index',
+ children: [
+ {
+ path: 'index',
+ component: () => import('@/views/guide/index'),
+ name: 'Guide',
+ meta: { title: 'guide', icon: 'guide', noCache: true }
+ }
+ ]
}
]
@@ -67,114 +114,95 @@ export const asyncRouterMap = [
path: '/permission',
component: Layout,
redirect: '/permission/index',
- meta: { roles: ['admin'] }, // you can set roles in root nav
- children: [{
- path: 'index',
- component: _import('permission/index'),
- name: 'permission',
- meta: {
- title: 'permission',
- icon: 'lock',
- roles: ['admin'] // or you can only set roles in sub nav
+ alwaysShow: true, // will always show the root menu
+ meta: {
+ title: 'permission',
+ icon: 'lock',
+ roles: ['admin', 'editor'] // you can set roles in root nav
+ },
+ children: [
+ {
+ path: 'page',
+ component: () => import('@/views/permission/page'),
+ name: 'PagePermission',
+ meta: {
+ title: 'pagePermission',
+ roles: ['admin'] // or you can only set roles in sub nav
+ }
+ },
+ {
+ path: 'directive',
+ component: () => import('@/views/permission/directive'),
+ name: 'DirectivePermission',
+ meta: {
+ title: 'directivePermission'
+ // if do not set roles, means: this page does not require permission
+ }
}
- }]
+ ]
},
{
path: '/icon',
component: Layout,
- children: [{
- path: 'index',
- component: _import('svg-icons/index'),
- name: 'icons',
- meta: { title: 'icons', icon: 'icon', noCache: true }
- }]
- },
-
- {
- path: '/components',
- component: Layout,
- redirect: 'noredirect',
- name: 'component-demo',
- meta: {
- title: 'components',
- icon: 'component'
- },
children: [
- { 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' }},
- { path: 'sticky', component: _import('components-demo/sticky'), name: 'sticky-demo', meta: { title: 'sticky' }},
- { path: 'count-to', component: _import('components-demo/countTo'), name: 'countTo-demo', meta: { title: 'countTo' }},
- { 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: 'index',
+ component: () => import('@/views/svg-icons/index'),
+ name: 'Icons',
+ meta: { title: 'icons', icon: 'icon', noCache: true }
+ }
]
},
- {
- path: '/charts',
- component: Layout,
- redirect: 'noredirect',
- name: 'charts',
- meta: {
- title: 'charts',
- icon: 'chart'
- },
- children: [
- { path: 'keyboard', component: _import('charts/keyboard'), name: 'keyboardChart', meta: { title: 'keyboardChart', noCache: true }},
- { path: 'line', component: _import('charts/line'), name: 'lineChart', meta: { title: 'lineChart', noCache: true }},
- { path: 'mixchart', component: _import('charts/mixChart'), name: 'mixChart', meta: { title: 'mixChart', noCache: true }}
- ]
- },
+ /** When your routing table is too long, you can split it into small modules**/
+ componentsRouter,
+ chartsRouter,
+ nestedRouter,
+ tableRouter,
{
path: '/example',
component: Layout,
- redirect: '/example/table/complex-table',
- name: 'example',
+ redirect: '/example/list',
+ name: 'Example',
meta: {
title: 'example',
icon: 'example'
},
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: 'create',
+ component: () => import('@/views/example/create'),
+ name: 'CreateArticle',
+ meta: { title: 'createArticle', icon: 'edit' }
},
- { path: 'tab/index', icon: 'tab', component: _import('example/tab/index'), name: 'tab', meta: { title: 'tab' }}
+ {
+ path: 'edit/:id(\\d+)',
+ component: () => import('@/views/example/edit'),
+ name: 'EditArticle',
+ meta: { title: 'editArticle', noCache: true },
+ hidden: true
+ },
+ {
+ path: 'list',
+ component: () => import('@/views/example/list'),
+ name: 'ArticleList',
+ meta: { title: 'articleList', icon: 'list' }
+ }
]
},
{
- path: '/form',
+ path: '/tab',
component: Layout,
- redirect: 'noredirect',
- name: 'form',
- meta: {
- title: 'form',
- icon: 'form'
- },
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: 'index',
+ component: () => import('@/views/tab/index'),
+ name: 'Tab',
+ meta: { title: 'tab', icon: 'tab' }
+ }
]
},
@@ -182,14 +210,24 @@ export const asyncRouterMap = [
path: '/error',
component: Layout,
redirect: 'noredirect',
- name: 'errorPages',
+ name: 'ErrorPages',
meta: {
title: 'errorPages',
icon: '404'
},
children: [
- { path: '401', component: _import('errorPage/401'), name: 'page401', meta: { title: 'page401', noCache: true }},
- { path: '404', component: _import('errorPage/404'), name: 'page404', meta: { title: 'page404', noCache: true }}
+ {
+ path: '401',
+ component: () => import('@/views/errorPage/401'),
+ name: 'Page401',
+ meta: { title: 'page401', noCache: true }
+ },
+ {
+ path: '404',
+ component: () => import('@/views/errorPage/404'),
+ name: 'Page404',
+ meta: { title: 'page404', noCache: true }
+ }
]
},
@@ -197,22 +235,44 @@ export const asyncRouterMap = [
path: '/error-log',
component: Layout,
redirect: 'noredirect',
- children: [{ path: 'log', component: _import('errorLog/index'), name: 'errorLog', meta: { title: 'errorLog', icon: 'bug' }}]
+ children: [
+ {
+ path: 'log',
+ component: () => import('@/views/errorLog/index'),
+ name: 'ErrorLog',
+ meta: { title: 'errorLog', icon: 'bug' }
+ }
+ ]
},
{
path: '/excel',
component: Layout,
redirect: '/excel/export-excel',
- name: 'excel',
+ name: 'Excel',
meta: {
title: 'excel',
icon: 'excel'
},
children: [
- { path: 'export-excel', component: _import('excel/exportExcel'), name: 'exportExcel', meta: { title: 'exportExcel' }},
- { path: 'export-selected-excel', component: _import('excel/selectExcel'), name: 'selectExcel', meta: { title: 'selectExcel' }},
- { path: 'upload-excel', component: _import('excel/uploadExcel'), name: 'uploadExcel', meta: { title: 'uploadExcel' }}
+ {
+ path: 'export-excel',
+ component: () => import('@/views/excel/exportExcel'),
+ name: 'ExportExcel',
+ meta: { title: 'exportExcel' }
+ },
+ {
+ path: 'export-selected-excel',
+ component: () => import('@/views/excel/selectExcel'),
+ name: 'SelectExcel',
+ meta: { title: 'selectExcel' }
+ },
+ {
+ path: 'upload-excel',
+ component: () => import('@/views/excel/uploadExcel'),
+ name: 'UploadExcel',
+ meta: { title: 'uploadExcel' }
+ }
]
},
@@ -222,27 +282,66 @@ export const asyncRouterMap = [
redirect: '/zip/download',
alwaysShow: true,
meta: { title: 'zip', icon: 'zip' },
- children: [{ path: 'download', component: _import('zip/index'), name: 'exportZip', meta: { title: 'exportZip' }}]
+ children: [
+ {
+ path: 'download',
+ component: () => import('@/views/zip/index'),
+ name: 'ExportZip',
+ meta: { title: 'exportZip' }
+ }
+ ]
},
{
path: '/theme',
component: Layout,
redirect: 'noredirect',
- children: [{ path: 'index', component: _import('theme/index'), name: 'theme', meta: { title: 'theme', icon: 'theme' }}]
+ children: [
+ {
+ path: 'index',
+ component: () => import('@/views/theme/index'),
+ name: 'Theme',
+ meta: { title: 'theme', icon: 'theme' }
+ }
+ ]
},
{
path: '/clipboard',
component: Layout,
redirect: 'noredirect',
- children: [{ path: 'index', component: _import('clipboard/index'), name: 'clipboardDemo', meta: { title: 'clipboardDemo', icon: 'clipboard' }}]
+ children: [
+ {
+ path: 'index',
+ component: () => import('@/views/clipboard/index'),
+ name: 'ClipboardDemo',
+ meta: { title: 'clipboardDemo', icon: 'clipboard' }
+ }
+ ]
},
{
path: '/i18n',
component: Layout,
- children: [{ path: 'index', component: _import('i18n-demo/index'), name: 'i18n', meta: { title: 'i18n', icon: 'international' }}]
+ children: [
+ {
+ path: 'index',
+ component: () => import('@/views/i18n-demo/index'),
+ name: 'I18n',
+ meta: { title: 'i18n', icon: 'international' }
+ }
+ ]
+ },
+
+ {
+ path: 'external-link',
+ component: Layout,
+ children: [
+ {
+ path: 'https://github.com/PanJiaChen/vue-element-admin',
+ meta: { title: 'externalLink', icon: 'link' }
+ }
+ ]
},
{ path: '*', redirect: '/404', hidden: true }
diff --git a/src/router/modules/charts.js b/src/router/modules/charts.js
new file mode 100644
index 00000000..d11f6efd
--- /dev/null
+++ b/src/router/modules/charts.js
@@ -0,0 +1,36 @@
+/** When your routing table is too long, you can split it into small modules**/
+
+import Layout from '@/views/layout/Layout'
+
+const chartsRouter = {
+ path: '/charts',
+ component: Layout,
+ redirect: 'noredirect',
+ name: 'Charts',
+ meta: {
+ title: 'charts',
+ icon: 'chart'
+ },
+ children: [
+ {
+ path: 'keyboard',
+ component: () => import('@/views/charts/keyboard'),
+ name: 'KeyboardChart',
+ meta: { title: 'keyboardChart', noCache: true }
+ },
+ {
+ path: 'line',
+ component: () => import('@/views/charts/line'),
+ name: 'LineChart',
+ meta: { title: 'lineChart', noCache: true }
+ },
+ {
+ path: 'mixchart',
+ component: () => import('@/views/charts/mixChart'),
+ name: 'MixChart',
+ meta: { title: 'mixChart', noCache: true }
+ }
+ ]
+}
+
+export default chartsRouter
diff --git a/src/router/modules/components.js b/src/router/modules/components.js
new file mode 100644
index 00000000..56dad2b1
--- /dev/null
+++ b/src/router/modules/components.js
@@ -0,0 +1,96 @@
+/** When your routing table is too long, you can split it into small modules**/
+
+import Layout from '@/views/layout/Layout'
+
+const componentsRouter = {
+ path: '/components',
+ component: Layout,
+ redirect: 'noredirect',
+ name: 'ComponentDemo',
+ meta: {
+ title: 'components',
+ icon: 'component'
+ },
+ children: [
+ {
+ path: 'tinymce',
+ component: () => import('@/views/components-demo/tinymce'),
+ name: 'TinymceDemo',
+ meta: { title: 'tinymce' }
+ },
+ {
+ path: 'markdown',
+ component: () => import('@/views/components-demo/markdown'),
+ name: 'MarkdownDemo',
+ meta: { title: 'markdown' }
+ },
+ {
+ path: 'json-editor',
+ component: () => import('@/views/components-demo/jsonEditor'),
+ name: 'JsonEditorDemo',
+ meta: { title: 'jsonEditor' }
+ },
+ {
+ path: 'splitpane',
+ component: () => import('@/views/components-demo/splitpane'),
+ name: 'SplitpaneDemo',
+ meta: { title: 'splitPane' }
+ },
+ {
+ path: 'avatar-upload',
+ component: () => import('@/views/components-demo/avatarUpload'),
+ name: 'AvatarUploadDemo',
+ meta: { title: 'avatarUpload' }
+ },
+ {
+ path: 'dropzone',
+ component: () => import('@/views/components-demo/dropzone'),
+ name: 'DropzoneDemo',
+ meta: { title: 'dropzone' }
+ },
+ {
+ path: 'sticky',
+ component: () => import('@/views/components-demo/sticky'),
+ name: 'StickyDemo',
+ meta: { title: 'sticky' }
+ },
+ {
+ path: 'count-to',
+ component: () => import('@/views/components-demo/countTo'),
+ name: 'CountToDemo',
+ meta: { title: 'countTo' }
+ },
+ {
+ path: 'mixin',
+ component: () => import('@/views/components-demo/mixin'),
+ name: 'ComponentMixinDemo',
+ meta: { title: 'componentMixin' }
+ },
+ {
+ path: 'back-to-top',
+ component: () => import('@/views/components-demo/backToTop'),
+ name: 'BackToTopDemo',
+ meta: { title: 'backToTop' }
+ },
+ {
+ path: 'drag-dialog',
+ component: () => import('@/views/components-demo/dragDialog'),
+ name: 'DragDialogDemo',
+ meta: { title: 'dragDialog' }
+ },
+ {
+ path: 'dnd-list',
+ component: () => import('@/views/components-demo/dndList'),
+ name: 'DndListDemo',
+ meta: { title: 'dndList' }
+ },
+ {
+ path: 'drag-kanban',
+ component: () => import('@/views/components-demo/dragKanban'),
+ name: 'DragKanbanDemo',
+ meta: { title: 'dragKanban' }
+ }
+ ]
+}
+
+export default componentsRouter
diff --git a/src/router/modules/nested.js b/src/router/modules/nested.js
new file mode 100644
index 00000000..ad8e31f9
--- /dev/null
+++ b/src/router/modules/nested.js
@@ -0,0 +1,66 @@
+/** When your routing table is too long, you can split it into small modules**/
+
+import Layout from '@/views/layout/Layout'
+
+const nestedRouter = {
+ path: '/nested',
+ component: Layout,
+ redirect: '/nested/menu1/menu1-1',
+ name: 'Nested',
+ meta: {
+ title: 'nested',
+ icon: 'nested'
+ },
+ children: [
+ {
+ path: 'menu1',
+ component: () => import('@/views/nested/menu1/index'), // Parent router-view
+ name: 'Menu1',
+ meta: { title: 'menu1' },
+ redirect: '/nested/menu1/menu1-1',
+ children: [
+ {
+ path: 'menu1-1',
+ component: () => import('@/views/nested/menu1/menu1-1'),
+ name: 'Menu1-1',
+ meta: { title: 'menu1-1' }
+ },
+ {
+ path: 'menu1-2',
+ component: () => import('@/views/nested/menu1/menu1-2'),
+ name: 'Menu1-2',
+ redirect: '/nested/menu1/menu1-2/menu1-2-1',
+ meta: { title: 'menu1-2' },
+ children: [
+ {
+ path: 'menu1-2-1',
+ component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
+ name: 'Menu1-2-1',
+ meta: { title: 'menu1-2-1' }
+ },
+ {
+ path: 'menu1-2-2',
+ component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
+ name: 'Menu1-2-2',
+ meta: { title: 'menu1-2-2' }
+ }
+ ]
+ },
+ {
+ path: 'menu1-3',
+ component: () => import('@/views/nested/menu1/menu1-3'),
+ name: 'Menu1-3',
+ meta: { title: 'menu1-3' }
+ }
+ ]
+ },
+ {
+ path: 'menu2',
+ name: 'Menu2',
+ component: () => import('@/views/nested/menu2/index'),
+ meta: { title: 'menu2' }
+ }
+ ]
+}
+
+export default nestedRouter
diff --git a/src/router/modules/table.js b/src/router/modules/table.js
new file mode 100644
index 00000000..a9c4cb44
--- /dev/null
+++ b/src/router/modules/table.js
@@ -0,0 +1,53 @@
+/** When your routing table is too long, you can split it into small modules**/
+
+import Layout from '@/views/layout/Layout'
+
+const tableRouter = {
+ path: '/table',
+ component: Layout,
+ redirect: '/table/complex-table',
+ name: 'Table',
+ meta: {
+ title: 'Table',
+ icon: 'table'
+ },
+ children: [
+ {
+ path: 'dynamic-table',
+ component: () => import('@/views/table/dynamicTable/index'),
+ name: 'DynamicTable',
+ meta: { title: 'dynamicTable' }
+ },
+ {
+ path: 'drag-table',
+ component: () => import('@/views/table/dragTable'),
+ name: 'DragTable',
+ meta: { title: 'dragTable' }
+ },
+ {
+ path: 'inline-edit-table',
+ component: () => import('@/views/table/inlineEditTable'),
+ name: 'InlineEditTable',
+ meta: { title: 'inlineEditTable' }
+ },
+ {
+ path: 'tree-table',
+ component: () => import('@/views/table/treeTable/treeTable'),
+ name: 'TreeTableDemo',
+ meta: { title: 'treeTable' }
+ },
+ {
+ path: 'custom-tree-table',
+ component: () => import('@/views/table/treeTable/customTreeTable'),
+ name: 'CustomTreeTableDemo',
+ meta: { title: 'customTreeTable' }
+ },
+ {
+ path: 'complex-table',
+ component: () => import('@/views/table/complexTable'),
+ name: 'ComplexTable',
+ meta: { title: 'complexTable' }
+ }
+ ]
+}
+export default tableRouter
diff --git a/src/store/getters.js b/src/store/getters.js
index 8adc5e81..cf314f5c 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -1,6 +1,8 @@
const getters = {
sidebar: state => state.app.sidebar,
language: state => state.app.language,
+ size: state => state.app.size,
+ device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
diff --git a/src/store/modules/app.js b/src/store/modules/app.js
index 9eed667c..bc4fb478 100644
--- a/src/store/modules/app.js
+++ b/src/store/modules/app.js
@@ -3,9 +3,12 @@ import Cookies from 'js-cookie'
const app = {
state: {
sidebar: {
- opened: !+Cookies.get('sidebarStatus')
+ opened: !+Cookies.get('sidebarStatus'),
+ withoutAnimation: false
},
- language: Cookies.get('language') || 'en'
+ device: 'desktop',
+ language: Cookies.get('language') || 'en',
+ size: Cookies.get('size') || 'medium'
},
mutations: {
TOGGLE_SIDEBAR: state => {
@@ -15,18 +18,40 @@ const app = {
Cookies.set('sidebarStatus', 0)
}
state.sidebar.opened = !state.sidebar.opened
+ state.sidebar.withoutAnimation = false
+ },
+ CLOSE_SIDEBAR: (state, withoutAnimation) => {
+ Cookies.set('sidebarStatus', 1)
+ state.sidebar.opened = false
+ state.sidebar.withoutAnimation = withoutAnimation
+ },
+ TOGGLE_DEVICE: (state, device) => {
+ state.device = device
},
SET_LANGUAGE: (state, language) => {
state.language = language
Cookies.set('language', language)
+ },
+ SET_SIZE: (state, size) => {
+ state.size = size
+ Cookies.set('size', size)
}
},
actions: {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
+ closeSideBar({ commit }, { withoutAnimation }) {
+ commit('CLOSE_SIDEBAR', withoutAnimation)
+ },
+ toggleDevice({ commit }, device) {
+ commit('TOGGLE_DEVICE', device)
+ },
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
+ },
+ setSize({ commit }, size) {
+ commit('SET_SIZE', size)
}
}
}
diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js
index ce1aafa6..97de701e 100644
--- a/src/store/modules/permission.js
+++ b/src/store/modules/permission.js
@@ -7,7 +7,7 @@ import { asyncRouterMap, constantRouterMap } from '@/router'
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
- return roles.some(role => route.meta.roles.indexOf(role) >= 0)
+ return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
@@ -15,20 +15,23 @@ function hasPermission(roles, route) {
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
- * @param asyncRouterMap
+ * @param routes asyncRouterMap
* @param roles
*/
-function filterAsyncRouter(asyncRouterMap, roles) {
- const accessedRouters = asyncRouterMap.filter(route => {
- if (hasPermission(roles, route)) {
- if (route.children && route.children.length) {
- route.children = filterAsyncRouter(route.children, roles)
+function filterAsyncRouter(routes, roles) {
+ const res = []
+
+ routes.forEach(route => {
+ const tmp = { ...route }
+ if (hasPermission(roles, tmp)) {
+ if (tmp.children) {
+ tmp.children = filterAsyncRouter(tmp.children, roles)
}
- return true
+ res.push(tmp)
}
- return false
})
- return accessedRouters
+
+ return res
}
const permission = {
@@ -47,7 +50,7 @@ const permission = {
return new Promise(resolve => {
const { roles } = data
let accessedRouters
- if (roles.indexOf('admin') >= 0) {
+ if (roles.includes('admin')) {
accessedRouters = asyncRouterMap
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js
index 273d33bd..cbf9eeb7 100644
--- a/src/store/modules/tagsView.js
+++ b/src/store/modules/tagsView.js
@@ -4,24 +4,30 @@ const tagsView = {
cachedViews: []
},
mutations: {
- ADD_VISITED_VIEWS: (state, view) => {
+ ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
- state.visitedViews.push({
- name: view.name,
- path: view.path,
- title: view.meta.title || 'no-name'
- })
+ state.visitedViews.push(
+ Object.assign({}, view, {
+ title: view.meta.title || 'no-name'
+ })
+ )
+ },
+ ADD_CACHED_VIEW: (state, view) => {
+ if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
- DEL_VISITED_VIEWS: (state, view) => {
+
+ DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
+ },
+ DEL_CACHED_VIEW: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
@@ -30,47 +36,125 @@ const tagsView = {
}
}
},
- DEL_OTHERS_VIEWS: (state, view) => {
+
+ DEL_OTHERS_VISITED_VIEWS: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews = state.visitedViews.slice(i, i + 1)
break
}
}
+ },
+ DEL_OTHERS_CACHED_VIEWS: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
- state.cachedViews = state.cachedViews.slice(index, i + 1)
+ state.cachedViews = state.cachedViews.slice(index, index + 1)
break
}
}
},
- DEL_ALL_VIEWS: (state) => {
+
+ DEL_ALL_VISITED_VIEWS: state => {
state.visitedViews = []
+ },
+ DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
+ },
+
+ UPDATE_VISITED_VIEW: (state, view) => {
+ for (let v of state.visitedViews) {
+ if (v.path === view.path) {
+ v = Object.assign(v, view)
+ break
+ }
+ }
}
+
},
actions: {
- addVisitedViews({ commit }, view) {
- commit('ADD_VISITED_VIEWS', view)
+ addView({ dispatch }, view) {
+ dispatch('addVisitedView', view)
+ dispatch('addCachedView', view)
},
- delVisitedViews({ commit, state }, view) {
- return new Promise((resolve) => {
- commit('DEL_VISITED_VIEWS', view)
+ addVisitedView({ commit }, view) {
+ commit('ADD_VISITED_VIEW', view)
+ },
+ addCachedView({ commit }, view) {
+ commit('ADD_CACHED_VIEW', view)
+ },
+
+ delView({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delVisitedView', view)
+ dispatch('delCachedView', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delVisitedView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
- delOthersViews({ commit, state }, view) {
- return new Promise((resolve) => {
- commit('DEL_OTHERS_VIEWS', view)
+ delCachedView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_CACHED_VIEW', view)
+ resolve([...state.cachedViews])
+ })
+ },
+
+ delOthersViews({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delOthersVisitedViews', view)
+ dispatch('delOthersCachedViews', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delOthersVisitedViews({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
- delAllViews({ commit, state }) {
- return new Promise((resolve) => {
- commit('DEL_ALL_VIEWS')
+ delOthersCachedViews({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_OTHERS_CACHED_VIEWS', view)
+ resolve([...state.cachedViews])
+ })
+ },
+
+ delAllViews({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delAllVisitedViews', view)
+ dispatch('delAllCachedViews', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delAllVisitedViews({ commit, state }) {
+ return new Promise(resolve => {
+ commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
+ },
+ delAllCachedViews({ commit, state }) {
+ return new Promise(resolve => {
+ commit('DEL_ALL_CACHED_VIEWS')
+ resolve([...state.cachedViews])
+ })
+ },
+
+ updateVisitedView({ commit }, view) {
+ commit('UPDATE_VISITED_VIEW', view)
}
}
}
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 18c93570..0f7e2296 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -67,7 +67,13 @@ const user = {
reject('error')
}
const data = response.data
- commit('SET_ROLES', data.roles)
+
+ if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
+ commit('SET_ROLES', data.roles)
+ } else {
+ reject('getInfo: roles must be a non-null array !')
+ }
+
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
@@ -116,7 +122,7 @@ const user = {
},
// 动态修改权限
- ChangeRoles({ commit }, role) {
+ ChangeRoles({ commit, dispatch }, role) {
return new Promise(resolve => {
commit('SET_TOKEN', role)
setToken(role)
@@ -126,6 +132,7 @@ const user = {
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
+ dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单
resolve()
})
})
diff --git a/src/styles/btn.scss b/src/styles/btn.scss
index f3f75c16..0c5ee768 100644
--- a/src/styles/btn.scss
+++ b/src/styles/btn.scss
@@ -46,7 +46,6 @@
border-radius: 8px;
border: none;
outline: none;
- margin-right: 25px;
transition: 600ms ease all;
position: relative;
display: inline-block;
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index b159d16b..dc59591e 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -73,3 +73,10 @@
}
}
}
+
+//dropdown
+ .el-dropdown-menu{
+ a{
+ display: block
+ }
+}
diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss
index 2fed2b1d..804e6fd1 100644
--- a/src/styles/sidebar.scss
+++ b/src/styles/sidebar.scss
@@ -2,99 +2,129 @@
// 主体区域
.main-container {
min-height: 100%;
- transition: margin-left 0.28s;
+ transition: margin-left .28s;
margin-left: 180px;
- } // 侧边栏
+ position: relative;
+ }
+ // 侧边栏
.sidebar-container {
transition: width 0.28s;
- width: 180px!important;
+ width: 180px !important;
height: 100%;
position: fixed;
+ font-size: 0px;
top: 0;
bottom: 0;
left: 0;
z-index: 1001;
+ overflow: hidden;
+ //reset element-ui css
+ .horizontal-collapse-transition {
+ transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+ }
+ .scrollbar-wrapper {
+ overflow-x: hidden!important;
+ .el-scrollbar__view {
+ height: 100%;
+ }
+ }
+ .el-scrollbar__bar.is-vertical{
+ right: 0px;
+ }
+ .is-horizontal {
+ display: none;
+ }
a {
display: inline-block;
width: 100%;
+ overflow: hidden;
}
.svg-icon {
margin-right: 16px;
}
.el-menu {
border: none;
- width: 100%;
+ height: 100%;
+ width: 100% !important;
}
}
.hideSidebar {
- .sidebar-container,.sidebar-container .el-menu {
- width: 36px!important;
- // overflow: inherit;
+ .sidebar-container {
+ width: 36px !important;
}
.main-container {
margin-left: 36px;
}
- }
- .hideSidebar {
.submenu-title-noDropdown {
- padding-left: 10px!important;
+ padding-left: 10px !important;
position: relative;
- span {
- height: 0;
- width: 0;
- overflow: hidden;
- visibility: hidden;
- transition: opacity .3s cubic-bezier(.55, 0, .1, 1);
- opacity: 0;
- display: inline-block;
- }
- &:hover {
- span {
- display: block;
- border-radius: 3px;
- z-index: 1002;
- width: 140px;
- height: 56px;
- visibility: visible;
- position: absolute;
- right: -145px;
- text-align: left;
- text-indent: 20px;
- top: 0px;
- background-color: $subMenuBg!important;
- opacity: 1;
- }
+ .el-tooltip {
+ padding: 0 10px !important;
}
}
.el-submenu {
+ overflow: hidden;
&>.el-submenu__title {
- padding-left: 10px!important;
- &>span {
- display: none;
- }
+ padding-left: 10px !important;
.el-submenu__icon-arrow {
display: none;
}
}
- .nest-menu {
- .el-submenu__icon-arrow {
- display: block!important;
- }
- span {
- display: inline-block!important;
+ }
+ .el-menu--collapse {
+ .el-submenu {
+ &>.el-submenu__title {
+ &>span {
+ height: 0;
+ width: 0;
+ overflow: hidden;
+ visibility: hidden;
+ display: inline-block;
+ }
}
}
}
}
- .nest-menu .el-submenu>.el-submenu__title,
- .el-submenu .el-menu-item {
- min-width: 180px!important;
- background-color: $subMenuBg!important;
+ .sidebar-container .nest-menu .el-submenu>.el-submenu__title,
+ .sidebar-container .el-submenu .el-menu-item {
+ min-width: 180px !important;
+ background-color: $subMenuBg !important;
&:hover {
- background-color: $menuHover!important;
+ background-color: $menuHover !important;
}
}
- .el-menu--collapse .el-menu .el-submenu{
- min-width: 180px!important;
+ .el-menu--collapse .el-menu .el-submenu {
+ min-width: 180px !important;
+ }
+
+ //适配移动端
+ .mobile {
+ .main-container {
+ margin-left: 0px;
+ }
+ .sidebar-container {
+ transition: transform .28s;
+ width: 180px !important;
+ }
+ &.hideSidebar {
+ .sidebar-container {
+ transition-duration: 0.3s;
+ transform: translate3d(-180px, 0, 0);
+ }
+ }
+ }
+ .withoutAnimation {
+ .main-container,
+ .sidebar-container {
+ transition: none;
+ }
+ }
+}
+
+.el-menu--vertical{
+ & >.el-menu{
+ .svg-icon{
+ margin-right: 16px;
+ }
}
}
diff --git a/src/styles/transition.scss b/src/styles/transition.scss
index 85c03286..04e16279 100644
--- a/src/styles/transition.scss
+++ b/src/styles/transition.scss
@@ -11,7 +11,21 @@
opacity: 0;
}
-/*fade*/
+/*fade-transform*/
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+ transition: all .5s;
+}
+.fade-transform-enter {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+.fade-transform-leave-to {
+ opacity: 0;
+ transform: translateX(30px);
+}
+
+/*breadcrumb transition*/
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
diff --git a/src/utils/index.js b/src/utils/index.js
index 2140fdff..f607910c 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -25,7 +25,8 @@ export function parseTime(time, cFormat) {
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
- if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
@@ -43,7 +44,8 @@ export function formatTime(time, option) {
if (diff < 30) {
return '刚刚'
- } else if (diff < 3600) { // less 1 hour
+ } else if (diff < 3600) {
+ // less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
@@ -53,7 +55,17 @@ export function formatTime(time, option) {
if (option) {
return parseTime(time, option)
} else {
- return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
+ return (
+ d.getMonth() +
+ 1 +
+ '月' +
+ d.getDate() +
+ '日' +
+ d.getHours() +
+ '时' +
+ d.getMinutes() +
+ '分'
+ )
}
}
@@ -81,9 +93,11 @@ export function getQueryObject(url) {
export function getByteLen(val) {
let len = 0
for (let i = 0; i < val.length; i++) {
- if (val[i].match(/[^\x00-\xff]/ig) != null) {
+ if (val[i].match(/[^\x00-\xff]/gi) != null) {
len += 1
- } else { len += 0.5 }
+ } else {
+ len += 0.5
+ }
}
return Math.floor(len)
}
@@ -100,11 +114,12 @@ export function cleanArray(actual) {
export function param(json) {
if (!json) return ''
- return cleanArray(Object.keys(json).map(key => {
- if (json[key] === undefined) return ''
- return encodeURIComponent(key) + '=' +
- encodeURIComponent(json[key])
- })).join('&')
+ return cleanArray(
+ Object.keys(json).map(key => {
+ if (json[key] === undefined) return ''
+ return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+ })
+ ).join('&')
}
export function param2Obj(url) {
@@ -112,7 +127,14 @@ export function param2Obj(url) {
if (!search) {
return {}
}
- return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
+ return JSON.parse(
+ '{"' +
+ decodeURIComponent(search)
+ .replace(/"/g, '\\"')
+ .replace(/&/g, '","')
+ .replace(/=/g, '":"') +
+ '"}'
+ )
}
export function html2Text(val) {
@@ -131,25 +153,22 @@ export function objectMerge(target, source) {
if (Array.isArray(source)) {
return source.slice()
}
- for (const property in source) {
- if (source.hasOwnProperty(property)) {
- const sourceProperty = source[property]
- if (typeof sourceProperty === 'object') {
- target[property] = objectMerge(target[property], sourceProperty)
- continue
- }
+ Object.keys(source).forEach(property => {
+ const sourceProperty = source[property]
+ if (typeof sourceProperty === 'object') {
+ target[property] = objectMerge(target[property], sourceProperty)
+ } else {
target[property] = sourceProperty
}
- }
+ })
return target
}
export function scrollTo(element, to, duration) {
if (duration <= 0) return
const difference = to - element.scrollTop
- const perTick = difference / duration * 10
+ const perTick = (difference / duration) * 10
setTimeout(() => {
- console.log(new Date())
element.scrollTop = element.scrollTop + perTick
if (element.scrollTop === to) return
scrollTo(element, to, duration - 10)
@@ -165,7 +184,9 @@ export function toggleClass(element, className) {
if (nameIndex === -1) {
classString += '' + className
} else {
- classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length)
+ classString =
+ classString.substr(0, nameIndex) +
+ classString.substr(nameIndex + className.length)
}
element.className = classString
}
@@ -179,7 +200,8 @@ export const pickerOptions = [
end.setTime(start.getTime())
picker.$emit('pick', [start, end])
}
- }, {
+ },
+ {
text: '最近一周',
onClick(picker) {
const end = new Date(new Date().toDateString())
@@ -187,7 +209,8 @@ export const pickerOptions = [
start.setTime(end.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end])
}
- }, {
+ },
+ {
text: '最近一个月',
onClick(picker) {
const end = new Date(new Date().toDateString())
@@ -195,7 +218,8 @@ export const pickerOptions = [
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
- }, {
+ },
+ {
text: '最近三个月',
onClick(picker) {
const end = new Date(new Date().toDateString())
@@ -203,7 +227,8 @@ export const pickerOptions = [
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end])
}
- }]
+ }
+]
export function getTime(type) {
if (type === 'start') {
@@ -248,20 +273,26 @@ export function debounce(func, wait, immediate) {
}
}
+/**
+ * This is just a simple version of deep copy
+ * Has a lot of edge cases bug
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+ */
export function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'shallowClone')
}
const targetObj = source.constructor === Array ? [] : {}
- for (const keys in source) {
- if (source.hasOwnProperty(keys)) {
- if (source[keys] && typeof source[keys] === 'object') {
- targetObj[keys] = source[keys].constructor === Array ? [] : {}
- targetObj[keys] = deepClone(source[keys])
- } else {
- targetObj[keys] = source[keys]
- }
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
}
- }
+ })
return targetObj
}
+
+export function uniqueArr(arr) {
+ return Array.from(new Set(arr))
+}
diff --git a/src/utils/permission.js b/src/utils/permission.js
new file mode 100644
index 00000000..221d3842
--- /dev/null
+++ b/src/utils/permission.js
@@ -0,0 +1,25 @@
+import store from '@/store'
+
+/**
+ * @param {Array} value
+ * @returns {Boolean}
+ * @example see @/views/permission/directive.vue
+ */
+export default function checkPermission(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const roles = store.getters && store.getters.roles
+ const permissionRoles = value
+
+ const hasPermission = roles.some(role => {
+ return permissionRoles.includes(role)
+ })
+
+ if (!hasPermission) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like v-permission="['admin','editor']"`)
+ return false
+ }
+}
diff --git a/src/utils/request.js b/src/utils/request.js
index eb70b363..50f9ecec 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -5,61 +5,72 @@ import { getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
- baseURL: process.env.BASE_API, // api的base_url
+ baseURL: process.env.BASE_API, // api 的 base_url
timeout: 5000 // request timeout
})
// request interceptor
-service.interceptors.request.use(config => {
- // Do something before request is sent
- if (store.getters.token) {
- config.headers['X-Token'] = getToken() // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
+service.interceptors.request.use(
+ config => {
+ // Do something before request is sent
+ if (store.getters.token) {
+ // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
+ config.headers['X-Token'] = getToken()
+ }
+ return config
+ },
+ error => {
+ // Do something with request error
+ console.log(error) // for debug
+ Promise.reject(error)
}
- return config
-}, error => {
- // Do something with request error
- console.log(error) // for debug
- Promise.reject(error)
-})
+)
-// respone interceptor
+// response interceptor
service.interceptors.response.use(
response => response,
/**
- * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页
- * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中
- */
- // const res = response.data;
- // if (res.code !== 20000) {
- // Message({
- // message: res.message,
- // type: 'error',
- // duration: 5 * 1000
- // });
- // // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
- // if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
- // MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
- // confirmButtonText: '重新登录',
- // cancelButtonText: '取消',
- // type: 'warning'
- // }).then(() => {
- // store.dispatch('FedLogOut').then(() => {
- // location.reload();// 为了重新实例化vue-router对象 避免bug
- // });
+ * 下面的注释为通过在response里,自定义code来标示请求状态
+ * 当code返回如下情况则说明权限有问题,登出并返回到登录页
+ * 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中
+ * 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
+ */
+ // response => {
+ // const res = response.data
+ // if (res.code !== 20000) {
+ // Message({
+ // message: res.message,
+ // type: 'error',
+ // duration: 5 * 1000
+ // })
+ // // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
+ // if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
+ // // 请自行在引入 MessageBox
+ // // import { Message, MessageBox } from 'element-ui'
+ // MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
+ // confirmButtonText: '重新登录',
+ // cancelButtonText: '取消',
+ // type: 'warning'
+ // }).then(() => {
+ // store.dispatch('FedLogOut').then(() => {
+ // location.reload() // 为了重新实例化vue-router对象 避免bug
// })
- // }
- // return Promise.reject('error');
- // } else {
- // return response.data;
+ // })
// }
+ // return Promise.reject('error')
+ // } else {
+ // return response.data
+ // }
+ // },
error => {
- console.log('err' + error)// for debug
+ console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
- })
+ }
+)
export default service
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 5bdd1b43..ada0e7e2 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -26,7 +26,7 @@ export function validateUpperCase(str) {
}
/* 大小写字母*/
-export function validatAlphabets(str) {
+export function validateAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
@@ -40,4 +40,3 @@ export function validateEmail(email) {
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return re.test(email)
}
-
diff --git a/src/vendor/Blob.js b/src/vendor/Blob.js
deleted file mode 100644
index 26382ccd..00000000
--- a/src/vendor/Blob.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/* eslint-disable */
-/* Blob.js
- * A Blob implementation.
- * 2014-05-27
- *
- * By Eli Grey, http://eligrey.com
- * By Devin Samarin, https://github.com/eboyjr
- * License: X11/MIT
- * See LICENSE.md
- */
-
-/*global self, unescape */
-/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
- plusplus: true */
-
-/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
-
-(function (view) {
- "use strict";
-
- view.URL = view.URL || view.webkitURL;
-
- if (view.Blob && view.URL) {
- try {
- new Blob;
- return;
- } catch (e) {}
- }
-
- // Internally we use a BlobBuilder implementation to base Blob off of
- // in order to support older browsers that only have BlobBuilder
- var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
- var
- get_class = function(object) {
- return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
- }
- , FakeBlobBuilder = function BlobBuilder() {
- this.data = [];
- }
- , FakeBlob = function Blob(data, type, encoding) {
- this.data = data;
- this.size = data.length;
- this.type = type;
- this.encoding = encoding;
- }
- , FBB_proto = FakeBlobBuilder.prototype
- , FB_proto = FakeBlob.prototype
- , FileReaderSync = view.FileReaderSync
- , FileException = function(type) {
- this.code = this[this.name = type];
- }
- , file_ex_codes = (
- "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
- + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
- ).split(" ")
- , file_ex_code = file_ex_codes.length
- , real_URL = view.URL || view.webkitURL || view
- , real_create_object_URL = real_URL.createObjectURL
- , real_revoke_object_URL = real_URL.revokeObjectURL
- , URL = real_URL
- , btoa = view.btoa
- , atob = view.atob
-
- , ArrayBuffer = view.ArrayBuffer
- , Uint8Array = view.Uint8Array
- ;
- FakeBlob.fake = FB_proto.fake = true;
- while (file_ex_code--) {
- FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
- }
- if (!real_URL.createObjectURL) {
- URL = view.URL = {};
- }
- URL.createObjectURL = function(blob) {
- var
- type = blob.type
- , data_URI_header
- ;
- if (type === null) {
- type = "application/octet-stream";
- }
- if (blob instanceof FakeBlob) {
- data_URI_header = "data:" + type;
- if (blob.encoding === "base64") {
- return data_URI_header + ";base64," + blob.data;
- } else if (blob.encoding === "URI") {
- return data_URI_header + "," + decodeURIComponent(blob.data);
- } if (btoa) {
- return data_URI_header + ";base64," + btoa(blob.data);
- } else {
- return data_URI_header + "," + encodeURIComponent(blob.data);
- }
- } else if (real_create_object_URL) {
- return real_create_object_URL.call(real_URL, blob);
- }
- };
- URL.revokeObjectURL = function(object_URL) {
- if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
- real_revoke_object_URL.call(real_URL, object_URL);
- }
- };
- FBB_proto.append = function(data/*, endings*/) {
- var bb = this.data;
- // decode data to a binary string
- if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
- var
- str = ""
- , buf = new Uint8Array(data)
- , i = 0
- , buf_len = buf.length
- ;
- for (; i < buf_len; i++) {
- str += String.fromCharCode(buf[i]);
- }
- bb.push(str);
- } else if (get_class(data) === "Blob" || get_class(data) === "File") {
- if (FileReaderSync) {
- var fr = new FileReaderSync;
- bb.push(fr.readAsBinaryString(data));
- } else {
- // async FileReader won't work as BlobBuilder is sync
- throw new FileException("NOT_READABLE_ERR");
- }
- } else if (data instanceof FakeBlob) {
- if (data.encoding === "base64" && atob) {
- bb.push(atob(data.data));
- } else if (data.encoding === "URI") {
- bb.push(decodeURIComponent(data.data));
- } else if (data.encoding === "raw") {
- bb.push(data.data);
- }
- } else {
- if (typeof data !== "string") {
- data += ""; // convert unsupported types to strings
- }
- // decode UTF-16 to binary string
- bb.push(unescape(encodeURIComponent(data)));
- }
- };
- FBB_proto.getBlob = function(type) {
- if (!arguments.length) {
- type = null;
- }
- return new FakeBlob(this.data.join(""), type, "raw");
- };
- FBB_proto.toString = function() {
- return "[object BlobBuilder]";
- };
- FB_proto.slice = function(start, end, type) {
- var args = arguments.length;
- if (args < 3) {
- type = null;
- }
- return new FakeBlob(
- this.data.slice(start, args > 1 ? end : this.data.length)
- , type
- , this.encoding
- );
- };
- FB_proto.toString = function() {
- return "[object Blob]";
- };
- FB_proto.close = function() {
- this.size = this.data.length = 0;
- };
- return FakeBlobBuilder;
- }(view));
-
- view.Blob = function Blob(blobParts, options) {
- var type = options ? (options.type || "") : "";
- var builder = new BlobBuilder();
- if (blobParts) {
- for (var i = 0, len = blobParts.length; i < len; i++) {
- builder.append(blobParts[i]);
- }
- }
- return builder.getBlob(type);
- };
-}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
diff --git a/src/vendor/Export2Excel.js b/src/vendor/Export2Excel.js
index 803eca25..ba956dc1 100644
--- a/src/vendor/Export2Excel.js
+++ b/src/vendor/Export2Excel.js
@@ -1,142 +1,182 @@
/* eslint-disable */
require('script-loader!file-saver');
-require('script-loader!@/vendor/Blob');
import XLSX from 'xlsx'
function generateArray(table) {
- var out = [];
- var rows = table.querySelectorAll('tr');
- var ranges = [];
- for (var R = 0; R < rows.length; ++R) {
- var outRow = [];
- var row = rows[R];
- var columns = row.querySelectorAll('td');
- for (var C = 0; C < columns.length; ++C) {
- var cell = columns[C];
- var colspan = cell.getAttribute('colspan');
- var rowspan = cell.getAttribute('rowspan');
- var cellValue = cell.innerText;
- if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
+ var out = [];
+ var rows = table.querySelectorAll('tr');
+ var ranges = [];
+ for (var R = 0; R < rows.length; ++R) {
+ var outRow = [];
+ var row = rows[R];
+ var columns = row.querySelectorAll('td');
+ for (var C = 0; C < columns.length; ++C) {
+ var cell = columns[C];
+ var colspan = cell.getAttribute('colspan');
+ var rowspan = cell.getAttribute('rowspan');
+ var cellValue = cell.innerText;
+ if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
- //Skip ranges
- ranges.forEach(function (range) {
- if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
- for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
- }
- });
-
- //Handle Row Span
- if (rowspan || colspan) {
- rowspan = rowspan || 1;
- colspan = colspan || 1;
- ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
- }
- ;
-
- //Handle Value
- outRow.push(cellValue !== "" ? cellValue : null);
-
- //Handle Colspan
- if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
+ //Skip ranges
+ ranges.forEach(function (range) {
+ if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
+ for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
- out.push(outRow);
+ });
+
+ //Handle Row Span
+ if (rowspan || colspan) {
+ rowspan = rowspan || 1;
+ colspan = colspan || 1;
+ ranges.push({
+ s: {
+ r: R,
+ c: outRow.length
+ },
+ e: {
+ r: R + rowspan - 1,
+ c: outRow.length + colspan - 1
+ }
+ });
+ };
+
+ //Handle Value
+ outRow.push(cellValue !== "" ? cellValue : null);
+
+ //Handle Colspan
+ if (colspan)
+ for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
- return [out, ranges];
+ out.push(outRow);
+ }
+ return [out, ranges];
};
function datenum(v, date1904) {
- if (date1904) v += 1462;
- var epoch = Date.parse(v);
- return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
+ if (date1904) v += 1462;
+ var epoch = Date.parse(v);
+ return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
- var ws = {};
- var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
- for (var R = 0; R != data.length; ++R) {
- for (var C = 0; C != data[R].length; ++C) {
- if (range.s.r > R) range.s.r = R;
- if (range.s.c > C) range.s.c = C;
- if (range.e.r < R) range.e.r = R;
- if (range.e.c < C) range.e.c = C;
- var cell = {v: data[R][C]};
- if (cell.v == null) continue;
- var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
-
- if (typeof cell.v === 'number') cell.t = 'n';
- else if (typeof cell.v === 'boolean') cell.t = 'b';
- else if (cell.v instanceof Date) {
- cell.t = 'n';
- cell.z = XLSX.SSF._table[14];
- cell.v = datenum(cell.v);
- }
- else cell.t = 's';
-
- ws[cell_ref] = cell;
- }
+ var ws = {};
+ var range = {
+ s: {
+ c: 10000000,
+ r: 10000000
+ },
+ e: {
+ c: 0,
+ r: 0
}
- if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
- return ws;
+ };
+ for (var R = 0; R != data.length; ++R) {
+ for (var C = 0; C != data[R].length; ++C) {
+ if (range.s.r > R) range.s.r = R;
+ if (range.s.c > C) range.s.c = C;
+ if (range.e.r < R) range.e.r = R;
+ if (range.e.c < C) range.e.c = C;
+ var cell = {
+ v: data[R][C]
+ };
+ if (cell.v == null) continue;
+ var cell_ref = XLSX.utils.encode_cell({
+ c: C,
+ r: R
+ });
+
+ if (typeof cell.v === 'number') cell.t = 'n';
+ else if (typeof cell.v === 'boolean') cell.t = 'b';
+ else if (cell.v instanceof Date) {
+ cell.t = 'n';
+ cell.z = XLSX.SSF._table[14];
+ cell.v = datenum(cell.v);
+ } else cell.t = 's';
+
+ ws[cell_ref] = cell;
+ }
+ }
+ if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
+ return ws;
}
function Workbook() {
- if (!(this instanceof Workbook)) return new Workbook();
- this.SheetNames = [];
- this.Sheets = {};
+ if (!(this instanceof Workbook)) return new Workbook();
+ this.SheetNames = [];
+ this.Sheets = {};
}
function s2ab(s) {
- var buf = new ArrayBuffer(s.length);
- var view = new Uint8Array(buf);
- for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
- return buf;
+ var buf = new ArrayBuffer(s.length);
+ var view = new Uint8Array(buf);
+ for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
+ return buf;
}
export function export_table_to_excel(id) {
- var theTable = document.getElementById(id);
- var oo = generateArray(theTable);
- var ranges = oo[1];
+ var theTable = document.getElementById(id);
+ var oo = generateArray(theTable);
+ var ranges = oo[1];
- /* original data */
- var data = oo[0];
- var ws_name = "SheetJS";
+ /* original data */
+ var data = oo[0];
+ var ws_name = "SheetJS";
- var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
+ var wb = new Workbook(),
+ ws = sheet_from_array_of_arrays(data);
- /* add ranges to worksheet */
- // ws['!cols'] = ['apple', 'banan'];
- ws['!merges'] = ranges;
+ /* add ranges to worksheet */
+ // ws['!cols'] = ['apple', 'banan'];
+ ws['!merges'] = ranges;
- /* add worksheet to workbook */
- wb.SheetNames.push(ws_name);
- wb.Sheets[ws_name] = ws;
+ /* add worksheet to workbook */
+ wb.SheetNames.push(ws_name);
+ wb.Sheets[ws_name] = ws;
- var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
+ var wbout = XLSX.write(wb, {
+ bookType: 'xlsx',
+ bookSST: false,
+ type: 'binary'
+ });
- saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
+ saveAs(new Blob([s2ab(wbout)], {
+ type: "application/octet-stream"
+ }), "test.xlsx")
}
-export function export_json_to_excel(th, jsonData, defaultTitle) {
-
- /* original data */
-
- var data = jsonData;
- data.unshift(th);
- var ws_name = "SheetJS";
-
- var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
+export function export_json_to_excel({
+ header,
+ data,
+ filename,
+ autoWidth = true,
+ bookType= 'xlsx'
+} = {}) {
+ /* original data */
+ filename = filename || 'excel-list'
+ data = [...data]
+ data.unshift(header);
+ var ws_name = "SheetJS";
+ var wb = new Workbook(),
+ ws = sheet_from_array_of_arrays(data);
+ if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map(row => row.map(val => {
/*先判断是否为null/undefined*/
if (val == null) {
- return {'wch': 10};
+ return {
+ 'wch': 10
+ };
}
/*再判断是否为中文*/
else if (val.toString().charCodeAt(0) > 255) {
- return {'wch': val.toString().length * 2};
+ return {
+ 'wch': val.toString().length * 2
+ };
} else {
- return {'wch': val.toString().length};
+ return {
+ 'wch': val.toString().length
+ };
}
}))
/*以第一行为初始值*/
@@ -149,12 +189,18 @@ export function export_json_to_excel(th, jsonData, defaultTitle) {
}
}
ws['!cols'] = result;
+ }
- /* add worksheet to workbook */
- wb.SheetNames.push(ws_name);
- wb.Sheets[ws_name] = ws;
+ /* add worksheet to workbook */
+ wb.SheetNames.push(ws_name);
+ wb.Sheets[ws_name] = ws;
- var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
- var title = defaultTitle || 'excel-list'
- saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
+ var wbout = XLSX.write(wb, {
+ bookType: bookType,
+ bookSST: false,
+ type: 'binary'
+ });
+ saveAs(new Blob([s2ab(wbout)], {
+ type: "application/octet-stream"
+ }), `${filename}.${bookType}`);
}
diff --git a/src/vendor/Export2Zip.js b/src/vendor/Export2Zip.js
index 6e11dc83..f776465e 100644
--- a/src/vendor/Export2Zip.js
+++ b/src/vendor/Export2Zip.js
@@ -14,7 +14,9 @@ export function export_txt_to_zip(th, jsonData, txtName, zipName) {
txtData += `${tempStr}\r\n`
})
zip.file(`${txt_name}.txt`, txtData)
- zip.generateAsync({type:"blob"}).then((blob) => {
+ zip.generateAsync({
+ type: "blob"
+ }).then((blob) => {
saveAs(blob, `${zip_name}.zip`)
}, (err) => {
alert('导出失败')
diff --git a/src/views/charts/keyboard.vue b/src/views/charts/keyboard.vue
index 30ed5762..3ea21397 100644
--- a/src/views/charts/keyboard.vue
+++ b/src/views/charts/keyboard.vue
@@ -1,6 +1,6 @@
-
-
+
+
@@ -8,7 +8,7 @@
import Chart from '@/components/Charts/keyboard'
export default {
- name: 'keyboardChart',
+ name: 'KeyboardChart',
components: { Chart }
}
@@ -16,9 +16,8 @@ export default {
diff --git a/src/views/charts/line.vue b/src/views/charts/line.vue
index c45c3813..2034d4c7 100644
--- a/src/views/charts/line.vue
+++ b/src/views/charts/line.vue
@@ -1,6 +1,6 @@
-
-
+
+
@@ -8,7 +8,7 @@
import Chart from '@/components/Charts/lineMarker'
export default {
- name: 'lineChart',
+ name: 'LineChart',
components: { Chart }
}
@@ -16,9 +16,8 @@ export default {
diff --git a/src/views/charts/mixChart.vue b/src/views/charts/mixChart.vue
index 1ca476e6..7ccc7fa0 100644
--- a/src/views/charts/mixChart.vue
+++ b/src/views/charts/mixChart.vue
@@ -1,6 +1,6 @@
-
-
+
+
@@ -8,7 +8,7 @@
import Chart from '@/components/Charts/mixChart'
export default {
- name: 'mixChart',
+ name: 'MixChart',
components: { Chart }
}
@@ -16,9 +16,8 @@ export default {
diff --git a/src/views/clipboard/index.vue b/src/views/clipboard/index.vue
index 83945235..607dfb66 100644
--- a/src/views/clipboard/index.vue
+++ b/src/views/clipboard/index.vue
@@ -2,12 +2,12 @@
-
- copy
+
+ copy
-
- copy
+
+ copy
@@ -18,7 +18,7 @@ import clip from '@/utils/clipboard' // use clipboard directly
import clipboard from '@/directive/clipboard/index.js' // use clipboard by v-directive
export default {
- name: 'clipboardDemo',
+ name: 'ClipboardDemo',
directives: {
clipboard
},
@@ -34,7 +34,7 @@ export default {
},
clipboardSuccess() {
this.$message({
- message: '复制成功',
+ message: 'Copy successfully',
type: 'success',
duration: 1500
})
diff --git a/src/views/components-demo/avatarUpload.vue b/src/views/components-demo/avatarUpload.vue
index f993a4f6..144448ce 100644
--- a/src/views/components-demo/avatarUpload.vue
+++ b/src/views/components-demo/avatarUpload.vue
@@ -2,16 +2,23 @@
This is based on
vue-image-crop-upload .
- {{$t('components.imageUploadTips')}}
+ {{ $t('components.imageUploadTips') }}
-
+
-
Change avatar
+ Change Avatar
-
+
@@ -20,7 +27,7 @@ import ImageCropper from '@/components/ImageCropper'
import PanThumb from '@/components/PanThumb'
export default {
- name: 'avatarUpload-demo',
+ name: 'AvatarUploadDemo',
components: { ImageCropper, PanThumb },
data() {
return {
diff --git a/src/views/components-demo/backToTop.vue b/src/views/components-demo/backToTop.vue
index 6abb652a..83a5529b 100644
--- a/src/views/components-demo/backToTop.vue
+++ b/src/views/components-demo/backToTop.vue
@@ -1,7 +1,7 @@
-
{{$t('components.backToTopTips1')}}
-
{{$t('components.backToTopTips2')}}
+
{{ $t('components.backToTopTips1') }}
+
{{ $t('components.backToTopTips2') }}
placeholder
placeholder
@@ -116,7 +116,7 @@
-
+
@@ -125,7 +125,7 @@
import BackToTop from '@/components/BackToTop'
export default {
- name: 'backToTop-demo',
+ name: 'BackToTopDemo',
components: { BackToTop },
data() {
return {
diff --git a/src/views/components-demo/countTo.vue b/src/views/components-demo/countTo.vue
index b30204d9..7044a5d2 100644
--- a/src/views/components-demo/countTo.vue
+++ b/src/views/components-demo/countTo.vue
@@ -3,37 +3,46 @@
countTo-component
-
+
-
<count-to :start-val='{{_startVal}}' :end-val='{{_endVal}}' :duration='{{_duration}}'
- :decimals='{{_decimals}}' :separator='{{_separator}}' :prefix='{{_prefix}}' :suffix='{{_suffix}}'
- :autoplay=false>
+
<count-to :start-val='{{ _startVal }}' :end-val='{{ _endVal }}' :duration='{{ _duration }}'
+ :decimals='{{ _decimals }}' :separator='{{ _separator }}' :prefix='{{ _prefix }}' :suffix='{{ _suffix }}'
+ :autoplay=false>
@@ -41,7 +50,7 @@
import countTo from 'vue-count-to'
export default {
- name: 'countTo-demo',
+ name: 'CountToDemo',
components: { countTo },
data() {
return {
@@ -202,4 +211,3 @@ input {
}
-
diff --git a/src/views/components-demo/dndList.vue b/src/views/components-demo/dndList.vue
index b9779a31..9c8847a9 100644
--- a/src/views/components-demo/dndList.vue
+++ b/src/views/components-demo/dndList.vue
@@ -4,7 +4,7 @@
Vue.Draggable
-
+
@@ -14,7 +14,7 @@ import DndList from '@/components/DndList'
import { fetchList } from '@/api/article'
export default {
- name: 'dndList-demo',
+ name: 'DndListDemo',
components: { DndList },
data() {
return {
@@ -37,4 +37,3 @@ export default {
}
-
diff --git a/src/views/components-demo/dragDialog.vue b/src/views/components-demo/dragDialog.vue
new file mode 100644
index 00000000..0a023f90
--- /dev/null
+++ b/src/views/components-demo/dragDialog.vue
@@ -0,0 +1,59 @@
+
+
+ open a Drag Dialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/components-demo/dragKanban.vue b/src/views/components-demo/dragKanban.vue
new file mode 100644
index 00000000..4353fb1e
--- /dev/null
+++ b/src/views/components-demo/dragKanban.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/components-demo/dropzone.vue b/src/views/components-demo/dropzone.vue
index a31a702b..0044a525 100644
--- a/src/views/components-demo/dropzone.vue
+++ b/src/views/components-demo/dropzone.vue
@@ -2,10 +2,10 @@
Based on dropzone .
- {{$t('components.dropzoneTips')}}
+ {{ $t('components.dropzoneTips') }}
-
+
@@ -14,7 +14,7 @@
import Dropzone from '@/components/Dropzone'
export default {
- name: 'dropzone-demo',
+ name: 'DropzoneDemo',
components: { Dropzone },
methods: {
dropzoneS(file) {
@@ -29,4 +29,3 @@ export default {
}
-
diff --git a/src/views/components-demo/jsonEditor.vue b/src/views/components-demo/jsonEditor.vue
index 75299bc0..cff3780c 100644
--- a/src/views/components-demo/jsonEditor.vue
+++ b/src/views/components-demo/jsonEditor.vue
@@ -2,7 +2,7 @@
JsonEditor is base on CodeMirrorr , lint base on json-lint
-
+
@@ -13,7 +13,7 @@ import JsonEditor from '@/components/JsonEditor'
const jsonData = '[{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"CORN"}],"name":""},{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"XAGUSD"},{"market_type":"forexdata","symbol":"AUTD"},{"market_type":"forexdata","symbol":"AGTD"}],"name":"贵金属"},{"items":[{"market_type":"forexdata","symbol":"CORN"},{"market_type":"forexdata","symbol":"WHEAT"},{"market_type":"forexdata","symbol":"SOYBEAN"},{"market_type":"forexdata","symbol":"SUGAR"}],"name":"农产品"},{"items":[{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"USOIL"},{"market_type":"forexdata","symbol":"NGAS"}],"name":"能源化工"}]'
export default {
- name: 'jsonEditor-demo',
+ name: 'JsonEditorDemo',
components: { JsonEditor },
data() {
return {
diff --git a/src/views/components-demo/markdown.vue b/src/views/components-demo/markdown.vue
index 61a3b51f..f60911d0 100644
--- a/src/views/components-demo/markdown.vue
+++ b/src/views/components-demo/markdown.vue
@@ -2,14 +2,14 @@
@@ -27,7 +27,7 @@ const content = `
`
export default {
- name: 'markdown-demo',
+ name: 'MarkdownDemo',
components: { MarkdownEditor },
data() {
return {
@@ -46,4 +46,3 @@ export default {
}
-
diff --git a/src/views/components-demo/mixin.vue b/src/views/components-demo/mixin.vue
index 78adb069..99b62468 100644
--- a/src/views/components-demo/mixin.vue
+++ b/src/views/components-demo/mixin.vue
@@ -7,19 +7,19 @@
- Components
+ Documentation
- Charts
+ Icons
- Excel
+ Excel
- Table
+ Table
- Form
+ Form
Theme
@@ -37,7 +37,7 @@
- 标题
+ 标题
@@ -74,20 +74,20 @@
hover text
-
+
-
+
Share
-
+
@@ -104,7 +104,7 @@ import DropdownMenu from '@/components/Share/dropdownMenu'
import waves from '@/directive/waves/index.js' // 水波纹指令
export default {
- name: 'componentMixin-demo',
+ name: 'ComponentMixinDemo',
components: {
PanThumb,
MdInput,
@@ -130,12 +130,11 @@ export default {
title: [{ required: true, trigger: 'change', validator: validate }]
},
articleList: [
- { title: '基础篇', href: 'https://segmentfault.com/a/1190000009275424' },
- { title: '登录权限篇', href: 'https://segmentfault.com/a/1190000009506097' },
- { title: '实战篇', href: 'https://segmentfault.com/a/1190000009762198' },
- { title: 'vueAdmin-template 篇', href: 'https://segmentfault.com/a/1190000010043013' },
- { title: '自行封装 component', href: 'https://segmentfault.com/a/1190000009090836' },
- { title: '优雅的使用 icon', href: 'https://segmentfault.com/a/https://segmentfault.com/a/1190000012213278' }
+ { title: '基础篇', href: 'https://juejin.im/post/59097cd7a22b9d0065fb61d2' },
+ { title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' },
+ { title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' },
+ { title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' },
+ { title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' }
]
}
}
diff --git a/src/views/components-demo/splitpane.vue b/src/views/components-demo/splitpane.vue
index d870197e..dcd87149 100644
--- a/src/views/components-demo/splitpane.vue
+++ b/src/views/components-demo/splitpane.vue
@@ -3,19 +3,19 @@
SplitPane If you've used
codepen ,
jsfiddle will not be unfamiliar.
- Github repository
+ Github repository
-
+
-
+
-
+
-
+
@@ -27,7 +27,7 @@
import splitPane from 'vue-splitpane'
export default {
- name: 'splitpane-demo',
+ name: 'SplitpaneDemo',
components: { splitPane },
methods: {
resize() {
@@ -38,30 +38,30 @@ export default {
diff --git a/src/views/components-demo/sticky.vue b/src/views/components-demo/sticky.vue
index 49772bea..65cfb091 100644
--- a/src/views/components-demo/sticky.vue
+++ b/src/views/components-demo/sticky.vue
@@ -1,14 +1,14 @@
-
+
- Platform
+ Platform
-
+
- {{item.name}}
+ {{ item.name }}
@@ -16,18 +16,17 @@
- Link
+ Link
-
-
+
+
Url
-
-
+
publish
@@ -35,7 +34,7 @@
-
Sticky header, {{$t('components.stickyTips')}}
+
Sticky header, {{ $t('components.stickyTips') }}
placeholder
placeholder
placeholder
@@ -92,12 +91,11 @@
-
diff --git a/src/views/dashboard/admin/components/LineChart.vue b/src/views/dashboard/admin/components/LineChart.vue
index 9be9c92d..ef493c4b 100644
--- a/src/views/dashboard/admin/components/LineChart.vue
+++ b/src/views/dashboard/admin/components/LineChart.vue
@@ -1,5 +1,5 @@
-
+
diff --git a/src/views/dashboard/admin/components/TransactionTable.vue b/src/views/dashboard/admin/components/TransactionTable.vue
index 90f4a914..07417523 100644
--- a/src/views/dashboard/admin/components/TransactionTable.vue
+++ b/src/views/dashboard/admin/components/TransactionTable.vue
@@ -1,18 +1,18 @@
-
+
- {{scope.row.order_no}}
+ {{ scope.row.order_no | orderNoFilter }}
- ¥{{scope.row.price | toThousandslsFilter}}
+ ¥{{ scope.row.price | toThousandFilter }}
- {{scope.row.status}}
+ {{ scope.row.status }}
@@ -22,11 +22,6 @@
import { fetchList } from '@/api/transaction'
export default {
- data() {
- return {
- list: null
- }
- },
filters: {
statusFilter(status) {
const statusMap = {
@@ -34,6 +29,14 @@ export default {
pending: 'danger'
}
return statusMap[status]
+ },
+ orderNoFilter(str) {
+ return str.substring(0, 30)
+ }
+ },
+ data() {
+ return {
+ list: null
}
},
created() {
@@ -42,7 +45,7 @@ export default {
methods: {
fetchData() {
fetchList().then(response => {
- this.list = response.data.items.slice(0, 7)
+ this.list = response.data.items.slice(0, 8)
})
}
}
diff --git a/src/views/dashboard/admin/index.vue b/src/views/dashboard/admin/index.vue
index e35aef26..1a79637a 100644
--- a/src/views/dashboard/admin/index.vue
+++ b/src/views/dashboard/admin/index.vue
@@ -1,40 +1,41 @@
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
@@ -72,7 +73,7 @@ const lineChartData = {
}
export default {
- name: 'dashboard-admin',
+ name: 'DashboardAdmin',
components: {
GithubCorner,
PanelGroup,
diff --git a/src/views/dashboard/editor/index.vue b/src/views/dashboard/editor/index.vue
index ae1f7995..ace11426 100644
--- a/src/views/dashboard/editor/index.vue
+++ b/src/views/dashboard/editor/index.vue
@@ -1,17 +1,17 @@
-
Your roles:
- {{item}}
+ Your roles:
+ {{ item }}
-
+
- {{name}}
- editor : dashboard
+ {{ name }}
+ Editor's Dashboard
-
+
@@ -22,7 +22,7 @@ import PanThumb from '@/components/PanThumb'
import GithubCorner from '@/components/GithubCorner'
export default {
- name: 'dashboard-editor',
+ name: 'DashboardEditor',
components: { PanThumb, GithubCorner },
data() {
return {
@@ -40,35 +40,34 @@ export default {
diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue
index 046f6e30..7011f6ad 100644
--- a/src/views/dashboard/index.vue
+++ b/src/views/dashboard/index.vue
@@ -1,6 +1,6 @@
-
+
@@ -10,7 +10,7 @@ import adminDashboard from './admin'
import editorDashboard from './editor'
export default {
- name: 'dashboard',
+ name: 'Dashboard',
components: { adminDashboard, editorDashboard },
data() {
return {
diff --git a/src/views/documentation/index.vue b/src/views/documentation/index.vue
index d8381592..4c7afc9d 100644
--- a/src/views/documentation/index.vue
+++ b/src/views/documentation/index.vue
@@ -1,25 +1,28 @@
diff --git a/src/views/errorLog/errorTestB.vue b/src/views/errorLog/errorTestB.vue
index a1303f89..b04c2511 100644
--- a/src/views/errorLog/errorTestB.vue
+++ b/src/views/errorLog/errorTestB.vue
@@ -1,5 +1,5 @@
-
+
diff --git a/src/views/errorPage/401.vue b/src/views/errorPage/401.vue
index e36c83a2..24420126 100644
--- a/src/views/errorPage/401.vue
+++ b/src/views/errorPage/401.vue
@@ -1,10 +1,10 @@
-
返回
+
返回
Oops!
- gif来源airbnb 页面
+ gif来源airbnb 页面
你没有权限去该页面
如有不满请联系你领导
-
-
+
+
@@ -30,7 +30,7 @@
import errGif from '@/assets/401_images/401.gif'
export default {
- name: 'page401',
+ name: 'Page401',
data() {
return {
errGif: errGif + '?' + +new Date(),
@@ -53,10 +53,12 @@ export default {
diff --git a/src/views/example/components/Dropdown/Comment.vue b/src/views/example/components/Dropdown/Comment.vue
new file mode 100644
index 00000000..77e8d5f1
--- /dev/null
+++ b/src/views/example/components/Dropdown/Comment.vue
@@ -0,0 +1,36 @@
+
+
+ {{ !comment_disabled?'评论已打开':'评论已关闭' }}
+
+
+
+
+
+ 关闭评论
+ 打开评论
+
+
+
+
+
+
+
diff --git a/src/views/example/components/Dropdown/Platform.vue b/src/views/example/components/Dropdown/Platform.vue
new file mode 100644
index 00000000..fce5e4b3
--- /dev/null
+++ b/src/views/example/components/Dropdown/Platform.vue
@@ -0,0 +1,46 @@
+
+
+
+ 平台({{ platforms.length }})
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
diff --git a/src/views/example/components/Dropdown/SourceUrl.vue b/src/views/example/components/Dropdown/SourceUrl.vue
new file mode 100644
index 00000000..d14e8549
--- /dev/null
+++ b/src/views/example/components/Dropdown/SourceUrl.vue
@@ -0,0 +1,36 @@
+
+
+
+ 外链
+
+
+
+
+
+ 填写url
+
+
+
+
+
+
+
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..77d90c26
--- /dev/null
+++ b/src/views/example/components/Warning.vue
@@ -0,0 +1,10 @@
+
+
+ 创建和编辑页面是不能被keep-alive 缓存的,因为keep-alive 的include 目前不支持根据路由来缓存,所以目前都是基于component name 来缓存的,如果你想要实现缓存的效果,可以使用localstorage 等浏览器缓存方案。或者不要使用keep-alive
+ 的include,直接缓存所有页面。详情见
+ 文档
+
+
+
diff --git a/src/views/form/create.vue b/src/views/example/create.vue
similarity index 66%
rename from src/views/form/create.vue
rename to src/views/example/create.vue
index ea5302dc..d0f7b787 100644
--- a/src/views/form/create.vue
+++ b/src/views/example/create.vue
@@ -1,12 +1,12 @@
-
+
diff --git a/src/views/form/edit.vue b/src/views/example/edit.vue
similarity index 67%
rename from src/views/form/edit.vue
rename to src/views/example/edit.vue
index 097b6140..c21af0c9 100644
--- a/src/views/form/edit.vue
+++ b/src/views/example/edit.vue
@@ -1,12 +1,12 @@
-
+
diff --git a/src/views/example/list.vue b/src/views/example/list.vue
new file mode 100644
index 00000000..f44d7078
--- /dev/null
+++ b/src/views/example/list.vue
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+ {{ scope.row.id }}
+
+
+
+
+
+ {{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}
+
+
+
+
+
+ {{ scope.row.author }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.status }}
+
+
+
+
+
+
+
+ {{ scope.row.title }}
+
+
+
+
+
+
+
+ Edit
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/example/table/dynamicTable/index.vue b/src/views/example/table/dynamicTable/index.vue
deleted file mode 100644
index 51f0da18..00000000
--- a/src/views/example/table/dynamicTable/index.vue
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
{{$t('table.dynamicTips1')}}
-
-
-
{{$t('table.dynamicTips2')}}
-
-
-
-
-
-
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 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/views/excel/components/AutoWidthOption.vue b/src/views/excel/components/AutoWidthOption.vue
new file mode 100644
index 00000000..06aad430
--- /dev/null
+++ b/src/views/excel/components/AutoWidthOption.vue
@@ -0,0 +1,30 @@
+
+
+ Cell Auto-Width:
+
+ True
+ False
+
+
+
+
+
diff --git a/src/views/excel/components/BookTypeOption.vue b/src/views/excel/components/BookTypeOption.vue
new file mode 100644
index 00000000..9970b0e4
--- /dev/null
+++ b/src/views/excel/components/BookTypeOption.vue
@@ -0,0 +1,38 @@
+
+
+ Book Type:
+
+
+
+
+
+
+
diff --git a/src/views/excel/components/FilenameOption.vue b/src/views/excel/components/FilenameOption.vue
new file mode 100644
index 00000000..5cc931ad
--- /dev/null
+++ b/src/views/excel/components/FilenameOption.vue
@@ -0,0 +1,28 @@
+
+
+
+ Filename:
+
+
+
+
+
diff --git a/src/views/excel/exportExcel.vue b/src/views/excel/exportExcel.vue
index be12ea4b..551b89f8 100644
--- a/src/views/excel/exportExcel.vue
+++ b/src/views/excel/exportExcel.vue
@@ -1,33 +1,42 @@
-
+
-
-
{{$t('excel.export')}} excel
-
-
+
+
+
+
+
- {{scope.$index}}
+ {{ scope.$index }}
- {{scope.row.title}}
+ {{ scope.row.title }}
- {{scope.row.author}}
+ {{ scope.row.author }}
- {{scope.row.pageviews}}
+ {{ scope.row.pageviews }}
-
- {{scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}')}}
+
+ {{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}
@@ -38,14 +47,22 @@
import { fetchList } from '@/api/article'
import { parseTime } from '@/utils'
+// options components
+import FilenameOption from './components/FilenameOption'
+import AutoWidthOption from './components/AutoWidthOption'
+import BookTypeOption from './components/BookTypeOption'
+
export default {
- name: 'exportExcel',
+ name: 'ExportExcel',
+ components: { FilenameOption, AutoWidthOption, BookTypeOption },
data() {
return {
list: null,
listLoading: true,
downloadLoading: false,
- filename: ''
+ filename: '',
+ autoWidth: true,
+ bookType: 'xlsx'
}
},
created() {
@@ -66,7 +83,13 @@ export default {
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
const list = this.list
const data = this.formatJson(filterVal, list)
- excel.export_json_to_excel(tHeader, data, this.filename)
+ excel.export_json_to_excel({
+ header: tHeader,
+ data,
+ filename: this.filename,
+ autoWidth: this.autoWidth,
+ bookType: this.bookType
+ })
this.downloadLoading = false
})
},
@@ -82,3 +105,13 @@ export default {
}
}
+
+
+
diff --git a/src/views/excel/selectExcel.vue b/src/views/excel/selectExcel.vue
index bd62ade7..2695bfb4 100644
--- a/src/views/excel/selectExcel.vue
+++ b/src/views/excel/selectExcel.vue
@@ -1,35 +1,45 @@
-
-
{{$t('excel.selectedExport')}}
-
-
-
+
+ {{ $t('excel.selectedExport') }}
+
+ Documentation
+
+
+
+
- {{scope.$index}}
+ {{ scope.$index }}
- {{scope.row.title}}
+ {{ scope.row.title }}
- {{scope.row.author}}
+ {{ scope.row.author }}
- {{scope.row.pageviews}}
+ {{ scope.row.pageviews }}
-
- {{scope.row.display_time}}
+
+ {{ scope.row.display_time }}
@@ -40,7 +50,7 @@
import { fetchList } from '@/api/article'
export default {
- name: 'selectExcel',
+ name: 'SelectExcel',
data() {
return {
list: null,
@@ -72,7 +82,11 @@ export default {
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
const list = this.multipleSelection
const data = this.formatJson(filterVal, list)
- excel.export_json_to_excel(tHeader, data, this.filename)
+ excel.export_json_to_excel({
+ header: tHeader,
+ data,
+ filename: this.filename
+ })
this.$refs.multipleTable.clearSelection()
this.downloadLoading = false
})
diff --git a/src/views/excel/uploadExcel.vue b/src/views/excel/uploadExcel.vue
index 187f43af..4095e910 100644
--- a/src/views/excel/uploadExcel.vue
+++ b/src/views/excel/uploadExcel.vue
@@ -1,9 +1,8 @@
-
+
-
-
+
@@ -12,7 +11,7 @@
import UploadExcelComponent from '@/components/UploadExcel/index.vue'
export default {
- name: 'uploadExcel',
+ name: 'UploadExcel',
components: { UploadExcelComponent },
data() {
return {
@@ -21,9 +20,22 @@ export default {
}
},
methods: {
- selected(data) {
- this.tableData = data.results
- this.tableHeader = data.header
+ beforeUpload(file) {
+ const isLt1M = file.size / 1024 / 1024 < 1
+
+ if (isLt1M) {
+ return true
+ }
+
+ this.$message({
+ message: 'Please do not upload files larger than 1m in size.',
+ type: 'warning'
+ })
+ return false
+ },
+ handleSuccess({ results, header }) {
+ this.tableData = results
+ this.tableHeader = header
}
}
}
diff --git a/src/views/form/components/ArticleDetail.vue b/src/views/form/components/ArticleDetail.vue
deleted file mode 100644
index ce9dc03d..00000000
--- a/src/views/form/components/ArticleDetail.vue
+++ /dev/null
@@ -1,314 +0,0 @@
-
-
-
-
-
-
-
-
- 创建form
-
-
-
- {{!postForm.comment_disabled?'评论已打开':'评论已关闭'}}
-
-
-
-
-
- 关闭评论
- 打开评论
-
-
-
-
-
-
- 平台
-
-
-
-
-
- {{item.name}}
-
-
-
-
-
-
-
- 外链
-
-
-
-
-
- 填写url
-
-
-
-
-
- 发布
-
- 草稿
-
-
-
- 发送异常错误,刷新页面,或者联系程序员
-
-
-
-
-
-
-
-
-
- 标题
-
- app可能会显示不全
-
-
-
-
-
-
-
- 无结果
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{contentShortLength}}字
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/guide/defineSteps.js b/src/views/guide/defineSteps.js
new file mode 100644
index 00000000..fde78926
--- /dev/null
+++ b/src/views/guide/defineSteps.js
@@ -0,0 +1,52 @@
+const steps = [
+ {
+ element: '.hamburger-container',
+ popover: {
+ title: 'Hamburger',
+ description: 'Open && Close sidebar',
+ position: 'bottom'
+ }
+ },
+ {
+ element: '.breadcrumb-container',
+ popover: {
+ title: 'Breadcrumb',
+ description: 'Indicate the current page location',
+ position: 'bottom'
+ }
+ },
+ {
+ element: '.screenfull',
+ popover: {
+ title: 'Screenfull',
+ description: 'Bring the page into fullscreen',
+ position: 'left'
+ }
+ },
+ {
+ element: '.international-icon',
+ popover: {
+ title: 'Switch language',
+ description: 'Switch the system language',
+ position: 'left'
+ }
+ },
+ {
+ element: '.theme-switch',
+ popover: {
+ title: 'Theme Switch',
+ description: 'Custom switch system theme',
+ position: 'left'
+ }
+ },
+ {
+ element: '.tags-view-container',
+ popover: {
+ title: 'Tags view',
+ description: 'The history of the page you visited',
+ position: 'bottom'
+ }
+ }
+]
+
+export default steps
diff --git a/src/views/guide/index.vue b/src/views/guide/index.vue
new file mode 100644
index 00000000..c30c52cf
--- /dev/null
+++ b/src/views/guide/index.vue
@@ -0,0 +1,34 @@
+
+
+
+ {{ $t('guide.description') }}
+ driver.js.
+
+
+
{{ $t('guide.button') }}
+
+
+
+
diff --git a/src/views/i18n-demo/index.vue b/src/views/i18n-demo/index.vue
index dc842a71..94d1e470 100644
--- a/src/views/i18n-demo/index.vue
+++ b/src/views/i18n-demo/index.vue
@@ -3,41 +3,45 @@
- {{$t('i18nView.title')}}
+ {{ $t('i18nView.title') }}
简体中文
English
- {{$t('i18nView.note')}}
+ {{ $t('i18nView.note') }}
-
+
-
+
-
-
+
+
+
- {{$t('i18nView.default')}}
- {{$t('i18nView.primary')}}
- {{$t('i18nView.success')}}
- {{$t('i18nView.info')}}
- {{$t('i18nView.warning')}}
- {{$t('i18nView.danger')}}
+ {{ $t('i18nView.default') }}
+ {{ $t('i18nView.primary') }}
+ {{ $t('i18nView.success') }}
+ {{ $t('i18nView.info') }}
+ {{ $t('i18nView.warning') }}
+ {{ $t('i18nView.danger') }}
-
+
-
-
-
+
+
+
@@ -49,11 +53,10 @@ import local from './local'
const viewName = 'i18nView'
export default {
- name: 'i18n',
+ name: 'I18n',
data() {
return {
date: '',
- currentPage: 5,
tableData: [{
date: '2016-05-03',
name: 'Tom',
@@ -73,13 +76,9 @@ export default {
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
- }]
- }
- },
- created() {
- if (!this.$i18n.getLocaleMessage('en')[viewName]) {
- this.$i18n.mergeLocaleMessage('en', local.en)
- this.$i18n.mergeLocaleMessage('zh', local.zh)
+ }],
+ options: [],
+ value: ''
}
},
computed: {
@@ -92,6 +91,36 @@ export default {
this.$store.dispatch('setLanguage', lang)
}
}
+ },
+ watch: {
+ lang() {
+ this.setOptions()
+ }
+ },
+ created() {
+ if (!this.$i18n.getLocaleMessage('en')[viewName]) {
+ this.$i18n.mergeLocaleMessage('en', local.en)
+ this.$i18n.mergeLocaleMessage('zh', local.zh)
+ }
+ this.setOptions() // set default select options
+ },
+ methods: {
+ setOptions() {
+ this.options = [
+ {
+ value: '1',
+ label: this.$t('i18nView.one')
+ },
+ {
+ value: '2',
+ label: this.$t('i18nView.two')
+ },
+ {
+ value: '3',
+ label: this.$t('i18nView.three')
+ }
+ ]
+ }
}
}
@@ -99,6 +128,7 @@ export default {
diff --git a/src/views/layout/components/AppMain.vue b/src/views/layout/components/AppMain.vue
index 653d1810..b6a3378f 100644
--- a/src/views/layout/components/AppMain.vue
+++ b/src/views/layout/components/AppMain.vue
@@ -1,8 +1,8 @@
-
-
+
@@ -14,10 +14,21 @@ 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()
- // }
}
}
+
+
+
diff --git a/src/views/layout/components/Navbar.vue b/src/views/layout/components/Navbar.vue
index ad96453c..7bae38e0 100644
--- a/src/views/layout/components/Navbar.vue
+++ b/src/views/layout/components/Navbar.vue
@@ -1,45 +1,51 @@
-
-
+
+
-
+
-
+
diff --git a/src/views/layout/components/Sidebar/Link.vue b/src/views/layout/components/Sidebar/Link.vue
new file mode 100644
index 00000000..07793b9a
--- /dev/null
+++ b/src/views/layout/components/Sidebar/Link.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/views/layout/components/Sidebar/SidebarItem.vue b/src/views/layout/components/Sidebar/SidebarItem.vue
index da07831b..9398af87 100644
--- a/src/views/layout/components/Sidebar/SidebarItem.vue
+++ b/src/views/layout/components/Sidebar/SidebarItem.vue
@@ -1,53 +1,106 @@
-