From 80f9a724dfcf5a6a9aae8ba05a024ee03f7edcab Mon Sep 17 00:00:00 2001 From: midfar Date: Fri, 10 Mar 2023 17:54:00 +0800 Subject: [PATCH] =?UTF-8?q?update:=20store=E3=80=81router=E4=BD=BF?= =?UTF-8?q?=E7=94=A8ts=E9=87=8D=E5=86=99=EF=BC=9B=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auto-imports.d.ts | 6 + components.d.ts | 69 ++++ mock/demo/_routes.js | 34 +- package-lock.json | 5 + package.json | 1 + src/api/user.js | 5 +- src/components/Charts/Keyboard.vue | 148 +++++++ src/components/Charts/LineMarker.vue | 208 ++++++++++ src/components/Charts/MixChart.vue | 266 ++++++++++++ src/components/Charts/mixins/resize.js | 56 +++ src/components/HeaderSearch/index.vue | 2 +- src/components/Pagination/index.vue | 102 +++++ src/directive/waves/index.js | 13 + src/directive/waves/waves.css | 26 ++ src/directive/waves/waves.js | 72 ++++ src/layout/components/Sidebar/Item.vue | 56 --- src/layout/components/Sidebar/SidebarItem.vue | 14 +- src/router/{index.js => index.ts} | 87 ++-- src/router/modules/{charts.js => charts.ts} | 8 +- src/router/modules/{table.js => table.ts} | 10 +- src/store/{index.js => index.ts} | 8 +- src/store/modules/app.js | 45 -- src/store/modules/app.ts | 47 +++ src/store/modules/permission.js | 67 --- src/store/modules/permission.ts | 68 +++ src/store/modules/settings.js | 30 -- src/store/modules/settings.ts | 24 ++ src/store/modules/tagsView.js | 93 ----- src/store/modules/tagsView.ts | 93 +++++ src/store/modules/user.js | 118 ------ src/store/modules/user.ts | 125 ++++++ src/views/charts/keyboard.vue | 24 ++ src/views/charts/line.vue | 24 ++ src/views/charts/mix-chart.vue | 24 ++ src/views/permission/role.vue | 11 +- src/views/table/complex-table.vue | 388 ++++++++++++++++++ src/views/table/drag-table.vue | 154 +++++++ .../dynamic-table/components/FixedThead.vue | 63 +++ .../dynamic-table/components/UnfixedThead.vue | 52 +++ src/views/table/dynamic-table/index.vue | 25 ++ src/views/table/inline-edit-table.vue | 157 +++++++ tsconfig.json | 2 +- 42 files changed, 2348 insertions(+), 482 deletions(-) create mode 100644 auto-imports.d.ts create mode 100644 components.d.ts create mode 100644 src/components/Charts/Keyboard.vue create mode 100644 src/components/Charts/LineMarker.vue create mode 100644 src/components/Charts/MixChart.vue create mode 100644 src/components/Charts/mixins/resize.js create mode 100644 src/components/Pagination/index.vue create mode 100644 src/directive/waves/index.js create mode 100644 src/directive/waves/waves.css create mode 100644 src/directive/waves/waves.js delete mode 100644 src/layout/components/Sidebar/Item.vue rename src/router/{index.js => index.ts} (78%) rename src/router/modules/{charts.js => charts.ts} (73%) rename src/router/modules/{table.js => table.ts} (75%) rename src/store/{index.js => index.ts} (76%) delete mode 100644 src/store/modules/app.js create mode 100644 src/store/modules/app.ts delete mode 100644 src/store/modules/permission.js create mode 100644 src/store/modules/permission.ts delete mode 100644 src/store/modules/settings.js create mode 100644 src/store/modules/settings.ts delete mode 100644 src/store/modules/tagsView.js create mode 100644 src/store/modules/tagsView.ts delete mode 100644 src/store/modules/user.js create mode 100644 src/store/modules/user.ts create mode 100644 src/views/charts/keyboard.vue create mode 100644 src/views/charts/line.vue create mode 100644 src/views/charts/mix-chart.vue create mode 100644 src/views/table/complex-table.vue create mode 100644 src/views/table/drag-table.vue create mode 100644 src/views/table/dynamic-table/components/FixedThead.vue create mode 100644 src/views/table/dynamic-table/components/UnfixedThead.vue create mode 100644 src/views/table/dynamic-table/index.vue create mode 100644 src/views/table/inline-edit-table.vue diff --git a/auto-imports.d.ts b/auto-imports.d.ts new file mode 100644 index 0000000..24e619c --- /dev/null +++ b/auto-imports.d.ts @@ -0,0 +1,6 @@ +// Generated by 'unplugin-auto-import' +export {} +declare global { + const ElMessage: typeof import('element-plus/es')['ElMessage'] + const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] +} diff --git a/components.d.ts b/components.d.ts new file mode 100644 index 0000000..1f77b3f --- /dev/null +++ b/components.d.ts @@ -0,0 +1,69 @@ +// generated by unplugin-vue-components +// We suggest you to commit this file into source control +// Read more: https://github.com/vuejs/core/pull/3399 +import '@vue/runtime-core' + +export {} + +declare module '@vue/runtime-core' { + export interface GlobalComponents { + Breadcrumb: typeof import('./src/components/Breadcrumb/index.vue')['default'] + DropdownMenu: typeof import('./src/components/Share/DropdownMenu.vue')['default'] + ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] + ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] + ElButton: typeof import('element-plus/es')['ElButton'] + ElCard: typeof import('element-plus/es')['ElCard'] + ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] + ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] + ElCol: typeof import('element-plus/es')['ElCol'] + ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] + ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] + ElDialog: typeof import('element-plus/es')['ElDialog'] + ElDropdown: typeof import('element-plus/es')['ElDropdown'] + ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] + ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] + ElForm: typeof import('element-plus/es')['ElForm'] + ElFormItem: typeof import('element-plus/es')['ElFormItem'] + ElIcon: typeof import('element-plus/es')['ElIcon'] + ElInput: typeof import('element-plus/es')['ElInput'] + ElMenu: typeof import('element-plus/es')['ElMenu'] + ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] + ElOption: typeof import('element-plus/es')['ElOption'] + ElPagination: typeof import('element-plus/es')['ElPagination'] + ElProgress: typeof import('element-plus/es')['ElProgress'] + ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] + ElRate: typeof import('element-plus/es')['ElRate'] + ElRow: typeof import('element-plus/es')['ElRow'] + ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] + ElSelect: typeof import('element-plus/es')['ElSelect'] + ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] + ElSwitch: typeof import('element-plus/es')['ElSwitch'] + ElTable: typeof import('element-plus/es')['ElTable'] + ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] + ElTabPane: typeof import('element-plus/es')['ElTabPane'] + ElTabs: typeof import('element-plus/es')['ElTabs'] + ElTag: typeof import('element-plus/es')['ElTag'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] + ElTree: typeof import('element-plus/es')['ElTree'] + GithubCorner: typeof import('./src/components/GithubCorner/index.vue')['default'] + Hamburger: typeof import('./src/components/Hamburger/index.vue')['default'] + HeaderSearch: typeof import('./src/components/HeaderSearch/index.vue')['default'] + Keyboard: typeof import('./src/components/Charts/Keyboard.vue')['default'] + LineMarker: typeof import('./src/components/Charts/LineMarker.vue')['default'] + Mallki: typeof import('./src/components/TextHoverEffect/Mallki.vue')['default'] + MixChart: typeof import('./src/components/Charts/MixChart.vue')['default'] + Pagination: typeof import('./src/components/Pagination/index.vue')['default'] + PanThumb: typeof import('./src/components/PanThumb/index.vue')['default'] + RightPanel: typeof import('./src/components/RightPanel/index.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + Screenfull: typeof import('./src/components/Screenfull/index.vue')['default'] + SizeSelect: typeof import('./src/components/SizeSelect/index.vue')['default'] + SvgIcon: typeof import('./src/components/SvgIcon/index.vue')['default'] + VueCountTo: typeof import('./src/components/vue-count-to/vue-countTo.vue')['default'] + } + export interface ComponentCustomProperties { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } +} diff --git a/mock/demo/_routes.js b/mock/demo/_routes.js index 2ee4fa3..faa10c9 100644 --- a/mock/demo/_routes.js +++ b/mock/demo/_routes.js @@ -4,7 +4,9 @@ export const constantRoutes = [ { path: '/redirect', component: 'layout/Layout', - hidden: true, + meta: { + hidden: true + }, children: [ { path: '/redirect/:path*', @@ -15,22 +17,30 @@ export const constantRoutes = [ { path: '/login', component: 'views/login/index', - hidden: true + meta: { + hidden: true + } }, { path: '/auth-redirect', component: 'views/login/auth-redirect', - hidden: true + meta: { + hidden: true + } }, { path: '/404', component: 'views/error-page/404', - hidden: true + meta: { + hidden: true + } }, { path: '/401', component: 'views/error-page/401', - hidden: true + meta: { + hidden: true + } }, { path: '', @@ -77,8 +87,8 @@ export const asyncRoutes = [ path: '/permission', component: 'layout/Layout', redirect: '/permission/index', - alwaysShow: true, meta: { + alwaysShow: true, title: 'Permission', icon: 'lock', roles: ['admin', 'editor'] @@ -333,8 +343,7 @@ export const asyncRoutes = [ path: 'edit/:id(\\d+)', component: 'views/example/edit', name: 'EditArticle', - meta: { title: 'Edit Article', noCache: true }, - hidden: true + meta: { hidden: true, title: 'Edit Article', noCache: true } }, { path: 'list', @@ -438,8 +447,7 @@ export const asyncRoutes = [ path: '/zip', component: 'layout/Layout', redirect: '/zip/download', - alwaysShow: true, - meta: { title: 'Zip', icon: 'zip' }, + meta: { alwaysShow: true, title: 'Zip', icon: 'zip' }, children: [ { path: 'download', @@ -466,7 +474,9 @@ export const asyncRoutes = [ { path: '/pdf/download', component: 'views/pdf/download', - hidden: true + meta: { + hidden: true + } }, { @@ -521,5 +531,5 @@ export const asyncRoutes = [ ] }, - { path: '*', redirect: '/404', hidden: true } + { path: '*', redirect: '/404', meta: { hidden: true }} ]; diff --git a/package-lock.json b/package-lock.json index 3983ddf..ce9e585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5901,6 +5901,11 @@ } } }, + "sortablejs": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/sortablejs/-/sortablejs-1.15.0.tgz", + "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", diff --git a/package.json b/package.json index 2baa816..a130df0 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "path-to-regexp": "6.2.1", "pinia": "2.0.28", "sass": "1.56.2", + "sortablejs": "1.15.0", "vue": "3.2.45", "vue-router": "4.1.6" }, diff --git a/src/api/user.js b/src/api/user.js index 02fcacc..37bc37f 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -16,9 +16,10 @@ export function getInfo(token) { }); } -export function logout() { +export function logout(token) { return request({ url: '/vue-element-admin/user/logout', - method: 'post' + method: 'post', + params: { token } }); } diff --git a/src/components/Charts/Keyboard.vue b/src/components/Charts/Keyboard.vue new file mode 100644 index 0000000..ad56e43 --- /dev/null +++ b/src/components/Charts/Keyboard.vue @@ -0,0 +1,148 @@ + + + diff --git a/src/components/Charts/LineMarker.vue b/src/components/Charts/LineMarker.vue new file mode 100644 index 0000000..a1f2d10 --- /dev/null +++ b/src/components/Charts/LineMarker.vue @@ -0,0 +1,208 @@ + + + diff --git a/src/components/Charts/MixChart.vue b/src/components/Charts/MixChart.vue new file mode 100644 index 0000000..262f6f6 --- /dev/null +++ b/src/components/Charts/MixChart.vue @@ -0,0 +1,266 @@ + + + diff --git a/src/components/Charts/mixins/resize.js b/src/components/Charts/mixins/resize.js new file mode 100644 index 0000000..d8ca5f0 --- /dev/null +++ b/src/components/Charts/mixins/resize.js @@ -0,0 +1,56 @@ +import { debounce } from '@/utils'; + +export default { + data() { + return { + $_sidebarElm: null, + $_resizeHandler: null + }; + }, + mounted() { + this.initListener(); + }, + activated() { + if (!this.$_resizeHandler) { + // avoid duplication init + this.initListener(); + } + + // when keep-alive chart activated, auto resize + this.resize(); + }, + beforeDestroy() { + this.destroyListener(); + }, + deactivated() { + this.destroyListener(); + }, + methods: { + // use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + $_sidebarResizeHandler(e) { + if (e.propertyName === 'width') { + this.$_resizeHandler(); + } + }, + initListener() { + this.$_resizeHandler = debounce(() => { + this.resize(); + }, 100); + window.addEventListener('resize', this.$_resizeHandler); + + this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]; + this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler); + }, + destroyListener() { + window.removeEventListener('resize', this.$_resizeHandler); + this.$_resizeHandler = null; + + this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler); + }, + resize() { + const { chart } = this; + chart && chart.resize(); + } + } +}; diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue index 4caa36b..3d22ee0 100644 --- a/src/components/HeaderSearch/index.vue +++ b/src/components/HeaderSearch/index.vue @@ -95,7 +95,7 @@ export default defineComponent({ for (const router of routes) { // skip hidden router - if (router.hidden) { continue; } + if (router.meta && router.meta.hidden) { continue; } const data = { path: path.resolve(basePath, router.path), diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue new file mode 100644 index 0000000..b97e17d --- /dev/null +++ b/src/components/Pagination/index.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/src/directive/waves/index.js b/src/directive/waves/index.js new file mode 100644 index 0000000..c38d799 --- /dev/null +++ b/src/directive/waves/index.js @@ -0,0 +1,13 @@ +import waves from './waves'; + +const install = function(Vue) { + Vue.directive('waves', waves); +}; + +if (window.Vue) { + window.waves = waves; + Vue.use(install); // eslint-disable-line +} + +waves.install = install; +export default waves; diff --git a/src/directive/waves/waves.css b/src/directive/waves/waves.css new file mode 100644 index 0000000..af7a7ef --- /dev/null +++ b/src/directive/waves/waves.css @@ -0,0 +1,26 @@ +.waves-ripple { + position: absolute; + border-radius: 100%; + background-color: rgba(0, 0, 0, 0.15); + background-clip: padding-box; + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + opacity: 1; +} + +.waves-ripple.z-active { + opacity: 0; + -webkit-transform: scale(2); + -ms-transform: scale(2); + transform: scale(2); + -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; + transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; + transition: opacity 1.2s ease-out, transform 0.6s ease-out; + transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out; +} \ No newline at end of file diff --git a/src/directive/waves/waves.js b/src/directive/waves/waves.js new file mode 100644 index 0000000..fc32338 --- /dev/null +++ b/src/directive/waves/waves.js @@ -0,0 +1,72 @@ +import './waves.css'; + +const context = '@@wavesContext'; + +function handleClick(el, binding) { + function handle(e) { + const customOpts = Object.assign({}, binding.value); + const opts = Object.assign({ + ele: el, // 波纹作用元素 + type: 'hit', // hit 点击位置扩散 center中心点扩展 + color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色 + }, + customOpts + ); + const target = opts.ele; + if (target) { + target.style.position = 'relative'; + target.style.overflow = 'hidden'; + const rect = target.getBoundingClientRect(); + let ripple = target.querySelector('.waves-ripple'); + if (!ripple) { + ripple = document.createElement('span'); + ripple.className = 'waves-ripple'; + ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'; + target.appendChild(ripple); + } else { + ripple.className = 'waves-ripple'; + } + switch (opts.type) { + case 'center': + ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px'; + ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px'; + break; + default: + ripple.style.top = + (e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop || + document.body.scrollTop) + 'px'; + ripple.style.left = + (e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft || + document.body.scrollLeft) + 'px'; + } + ripple.style.backgroundColor = opts.color; + ripple.className = 'waves-ripple z-active'; + return false; + } + } + + if (!el[context]) { + el[context] = { + removeHandle: handle + }; + } else { + el[context].removeHandle = handle; + } + + return handle; +} + +export default { + bind(el, binding) { + el.addEventListener('click', handleClick(el, binding), false); + }, + update(el, binding) { + el.removeEventListener('click', el[context].removeHandle, false); + el.addEventListener('click', handleClick(el, binding), false); + }, + unbind(el) { + el.removeEventListener('click', el[context].removeHandle, false); + el[context] = null; + delete el[context]; + } +}; diff --git a/src/layout/components/Sidebar/Item.vue b/src/layout/components/Sidebar/Item.vue deleted file mode 100644 index 62c08ce..0000000 --- a/src/layout/components/Sidebar/Item.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue index 437b815..875f059 100644 --- a/src/layout/components/Sidebar/SidebarItem.vue +++ b/src/layout/components/Sidebar/SidebarItem.vue @@ -1,7 +1,7 @@