diff --git a/.eslintrc.js b/.eslintrc.js index 2aec88b..4cad823 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,6 +24,7 @@ module.exports = defineConfig({ 'plugin:prettier/recommended' ], rules: { + 'vue/no-setup-props-destructure': 'off', 'vue/script-setup-uses-vars': 'error', 'vue/no-reserved-component-names': 'off', '@typescript-eslint/ban-ts-ignore': 'off', diff --git a/README.md b/README.md index ddc3778..390b166 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@


-[![license](https://img.shields.io/github/license/kailong321200875/vue-element-plus-admin.svg)](LICENSE) +[![license](https://img.shields.io/github/license/kailong321200875/vue-element-plus-admin.svg)](LICENSE) [![repo-size](https://img.shields.io/github/repo-size/kailong321200875/vue-element-plus-admin.svg)](repo-size) [![last-commit](https://img.shields.io/github/last-commit/kailong321200875/vue-element-plus-admin.svg)](last-commit) [![stars](https://img.shields.io/github/stars/kailong321200875/vue-element-plus-admin.svg)](stars) [![forks](https://img.shields.io/github/forks/kailong321200875/vue-element-plus-admin.svg)](forks) [![release](https://img.shields.io/github/release/kailong321200875/vue-element-plus-admin.svg)](release) [![watchers](https://img.shields.io/github/watchers/kailong321200875/vue-element-plus-admin.svg)](watchers)

vue-element-plus-admin

@@ -9,11 +9,11 @@ ## Introduction -vue-element-plus-admin is a free and open source middle and background template based on `element-plus`. Developed using the latest mainstream technologies such as `vue3`, `vite4` and `typescript`, the out of the box middle and background front-end solution can be used as the starting template of the project and learning reference. And always pay attention to the latest technological trends and update them as soon as possible. +vue-element-plus-admin is a free and open source middle and background template based on `element-plus`. Developed using the latest mainstream technologies such as `vue3`, `vite` and `typescript`, the out of the box middle and background front-end solution can be used as the starting template of the project and learning reference. And always pay attention to the latest technological trends and update them as soon as possible. vue-element-plus-admin is positioned as a background integration scheme, which is not suitable for secondary development as a basic template. Because it integrates many functions that you may not use, it will cause a lot of code redundancy. If your project doesn't pay attention to this problem, you can also directly carry out secondary development based on it. -If you need a basic template, please switch to the `tempalte` branch. `Tempalte` simply integrates some common layout functions such as layout and dynamic menu, which is more suitable for developers to carry out secondary development. +If you need a basic template, please switch to the `mini` branch. `mini` simply integrates some common layout functions such as layout and dynamic menu, which is more suitable for developers to carry out secondary development. ## Feature @@ -37,6 +37,8 @@ account: **admin/admin test/test** `test` account is used to simulate the front-end control authority. The server only returns the menu key to be displayed, and the front-end performs matching rendering +Online examples do not apply to menu filtering by default, but directly use Static routing + ## Documentation [Document Github](https://element-plus-admin-doc.cn/) @@ -127,6 +129,16 @@ Support modern browsers, not IE | :-: | :-: | :-: | :-: | :-: | | not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions | +## Donate + +If you find this project helpful, welcome sponsorship to show your support~ + + + +## Group + + + ## License [MIT](./LICENSE) diff --git a/README.zh-CN.md b/README.zh-CN.md index e7b24ad..4c1cbd1 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,6 +1,6 @@


-[![license](https://img.shields.io/github/license/kailong321200875/vue-element-plus-admin.svg)](LICENSE) +[![license](https://img.shields.io/github/license/kailong321200875/vue-element-plus-admin.svg)](LICENSE) [![repo-size](https://img.shields.io/github/repo-size/kailong321200875/vue-element-plus-admin.svg)](repo-size) [![last-commit](https://img.shields.io/github/last-commit/kailong321200875/vue-element-plus-admin.svg)](last-commit) [![stars](https://img.shields.io/github/stars/kailong321200875/vue-element-plus-admin.svg)](stars) [![forks](https://img.shields.io/github/forks/kailong321200875/vue-element-plus-admin.svg)](forks) [![release](https://img.shields.io/github/release/kailong321200875/vue-element-plus-admin.svg)](release) [![watchers](https://img.shields.io/github/watchers/kailong321200875/vue-element-plus-admin.svg)](watchers)

vue-element-plus-admin

@@ -9,11 +9,11 @@ ## 介绍 -vue-element-plus-admin 是一个基于 `element-plus` 免费开源的中后台模版。使用了最新的`vue3`,`vite4`,`TypeScript`等主流技术开发,开箱即用的中后台前端解决方案,可以用来作为项目的启动模版,也可用于学习参考。并且时刻关注着最新技术动向,尽可能的第一时间更新。 +vue-element-plus-admin 是一个基于 `element-plus` 免费开源的中后台模版。使用了最新的`vue3`,`vite`,`TypeScript`等主流技术开发,开箱即用的中后台前端解决方案,可以用来作为项目的启动模版,也可用于学习参考。并且时刻关注着最新技术动向,尽可能的第一时间更新。 vue-element-plus-admin 的定位是后台集成方案,不太适合当基础模板来进行二次开发。因为集成了很多你可能用不到的功能,会造成不少的代码冗余。如果你的项目不关注这方面的问题,也可以直接基于它进行二次开发。 -如需要基础模版,请切换到 `tempalte` 分支,`tempalte` 只简单集成了一些如:布局、动态菜单等常用布局功能,更适合开发者进行二次开发。 +如需要基础模版,请切换到 `mini` 分支,`mini` 只简单集成了一些如:布局、动态菜单等常用布局功能,更适合开发者进行二次开发。 ## 特性 @@ -37,6 +37,8 @@ vue-element-plus-admin 的定位是后台集成方案,不太适合当基础模 `test` 帐号用于模拟前端控制权限,服务端只返回需要显示的菜单 key,前端进行匹配渲染 +在线例子默认不适用菜单过滤,而是直接使用静态路由表 + ## 文档 [文档地址 Github](https://element-plus-admin-doc.cn/) @@ -127,6 +129,16 @@ pnpm run build:pro | :-: | :-: | :-: | :-: | :-: | | not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions | +## Donate + +如果你觉得这个项目有帮助,欢迎赞助以示支持~ + + + +## 交流群 + + + ## 许可证 [MIT](./LICENSE) diff --git a/mock/role/index.ts b/mock/role/index.ts index 3f93471..decf4ba 100644 --- a/mock/role/index.ts +++ b/mock/role/index.ts @@ -272,6 +272,37 @@ const adminList = [ } ] }, + { + path: '/function', + component: '#', + redirect: '/function/multipleTabs', + name: 'Function', + meta: { + title: 'router.function', + icon: 'ri:function-fill', + alwaysShow: true + }, + children: [ + { + path: 'multipleTabs', + component: 'views/Function/MultipleTabs', + name: 'MultipleTabs', + meta: { + title: 'router.multipleTabs' + } + }, + { + path: 'multipleTabs-demo/:id', + component: 'views/Function/MultipleTabsDemo', + name: 'MultipleTabsDemo', + meta: { + hidden: true, + title: 'router.details', + canTo: true + } + } + ] + }, { path: '/hooks', component: '#', @@ -561,6 +592,9 @@ const testList: string[] = [ '/components/infotip', '/Components/InputPassword', '/Components/Sticky', + 'function', + '/function/multiple-tabs', + '/function/multiple-tabs-demo/:id', '/hooks', '/hooks/useWatermark', '/hooks/useOpenTab', diff --git a/package.json b/package.json index fc03972..67b5de9 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,6 @@ "rollup": "^3.26.3", "stylelint": "^15.10.1", "stylelint-config-html": "^1.1.0", - "stylelint-config-prettier": "^9.0.5", "stylelint-config-recommended": "^13.0.0", "stylelint-config-standard": "^34.0.0", "stylelint-order": "^6.0.3", diff --git a/src/components/Collapse/src/Collapse.vue b/src/components/Collapse/src/Collapse.vue index f397af5..6d6362e 100644 --- a/src/components/Collapse/src/Collapse.vue +++ b/src/components/Collapse/src/Collapse.vue @@ -23,13 +23,12 @@ const toggleCollapse = () => { diff --git a/src/components/ContentWrap/src/ContentWrap.vue b/src/components/ContentWrap/src/ContentWrap.vue index 4538fc0..60c9aa9 100644 --- a/src/components/ContentWrap/src/ContentWrap.vue +++ b/src/components/ContentWrap/src/ContentWrap.vue @@ -24,6 +24,9 @@ defineProps({ +
+ +
diff --git a/src/components/TabMenu/src/TabMenu.vue b/src/components/TabMenu/src/TabMenu.vue index 8fcb54d..3305113 100644 --- a/src/components/TabMenu/src/TabMenu.vue +++ b/src/components/TabMenu/src/TabMenu.vue @@ -141,7 +141,7 @@ export default defineComponent({ id={`${variables.namespace}-menu`} class={[ prefixCls, - 'relative bg-[var(--left-menu-bg-color)] top-1px z-3000 layout-border__right', + 'relative bg-[var(--left-menu-bg-color)] top-1px layout-border__right', { 'w-[var(--tab-menu-max-width)]': !unref(collapse), 'w-[var(--tab-menu-min-width)]': unref(collapse) diff --git a/src/components/Table/src/Table.vue b/src/components/Table/src/Table.vue index c3ab442..ed964d2 100644 --- a/src/components/Table/src/Table.vue +++ b/src/components/Table/src/Table.vue @@ -362,7 +362,7 @@ export default defineComponent({ return children && children.length ? renderTreeTableColumn(children) : props?.slots?.default - ? props.slots.default(args) + ? props.slots.default(...args) : v?.formatter ? v?.formatter?.(data.row, data.column, get(data.row, v.field), data.$index) : isImageUrl @@ -371,7 +371,7 @@ export default defineComponent({ } } if (props?.slots?.header) { - slots['header'] = (...args: any[]) => props.slots.header(args) + slots['header'] = (...args: any[]) => props.slots.header(...args) } return ( @@ -459,7 +459,7 @@ export default defineComponent({ return children && children.length ? renderTreeTableColumn(children) : props?.slots?.default - ? props.slots.default(args) + ? props.slots.default(...args) : v?.formatter ? v?.formatter?.(data.row, data.column, get(data.row, v.field), data.$index) : isImageUrl @@ -468,7 +468,7 @@ export default defineComponent({ } } if (props?.slots?.header) { - slots['header'] = (...args: any[]) => props.slots.header(args) + slots['header'] = (...args: any[]) => props.slots.header(...args) } return ( diff --git a/src/locales/en.ts b/src/locales/en.ts index ba217d9..5a0042e 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -164,7 +164,10 @@ export default { department: 'Department management', menuManagement: 'Menu management', // 权限测试页面 - permission: 'Permission test page' + permission: 'Permission test page', + function: 'Function', + multipleTabs: 'Multiple tabs', + details: 'Details' }, permission: { hasPermission: 'Please set the operation permission value' diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 0957481..305f2ca 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -163,7 +163,10 @@ export default { PicturePreview: '表格图片预览', department: '部门管理', menuManagement: '菜单管理', - permission: '权限测试页' + permission: '权限测试页', + function: '功能', + multipleTabs: '多开标签页', + details: '详情页' }, permission: { hasPermission: '请设置操作权限值' diff --git a/src/permission.ts b/src/permission.ts index 48c8c4a..92eebfb 100644 --- a/src/permission.ts +++ b/src/permission.ts @@ -5,15 +5,15 @@ import type { RouteRecordRaw } from 'vue-router' import { useTitle } from '@/hooks/web/useTitle' import { useNProgress } from '@/hooks/web/useNProgress' import { usePermissionStoreWithOut } from '@/store/modules/permission' -import { useDictStoreWithOut } from '@/store/modules/dict' +// import { useDictStoreWithOut } from '@/store/modules/dict' import { usePageLoading } from '@/hooks/web/usePageLoading' -import { getDictApi } from '@/api/common' +// import { getDictApi } from '@/api/common' const permissionStore = usePermissionStoreWithOut() const appStore = useAppStoreWithOut() -const dictStore = useDictStoreWithOut() +// const dictStore = useDictStoreWithOut() const { getStorage } = useStorage() @@ -30,14 +30,14 @@ router.beforeEach(async (to, from, next) => { if (to.path === '/login') { next({ path: '/' }) } else { - if (!dictStore.getIsSetDict) { - // 获取所有字典 - const res = await getDictApi() - if (res) { - dictStore.setDictObj(res.data) - dictStore.setIsSetDict(true) - } - } + // if (!dictStore.getIsSetDict) { + // // 获取所有字典 + // const res = await getDictApi() + // if (res) { + // dictStore.setDictObj(res.data) + // dictStore.setIsSetDict(true) + // } + // } if (permissionStore.getIsAddRouters) { next() return diff --git a/src/router/index.ts b/src/router/index.ts index 36716fb..0e37e54 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -313,6 +313,37 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [ } ] }, + { + path: '/function', + component: Layout, + redirect: '/function/multipleTabs', + name: 'Function', + meta: { + title: t('router.function'), + icon: 'ri:function-fill', + alwaysShow: true + }, + children: [ + { + path: 'multiple-tabs', + component: () => import('@/views/Function/MultipleTabs.vue'), + name: 'MultipleTabs', + meta: { + title: t('router.multipleTabs') + } + }, + { + path: 'multiple-tabs-demo/:id', + component: () => import('@/views/Function/MultipleTabsDemo.vue'), + name: 'MultipleTabsDemo', + meta: { + hidden: true, + title: t('router.details'), + canTo: true + } + } + ] + }, { path: '/hooks', component: Layout, @@ -333,14 +364,6 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [ } } // { - // path: 'useOpenTab', - // component: () => import('@/views/hooks/useOpenTab.vue'), - // name: 'UseOpenTab', - // meta: { - // title: 'useOpenTab' - // } - // } - // { // path: 'useCrudSchemas', // component: () => import('@/views/hooks/useCrudSchemas.vue'), // name: 'UseCrudSchemas', diff --git a/src/views/Authorization/Department/Department.vue b/src/views/Authorization/Department/Department.vue index 864226a..6d52381 100644 --- a/src/views/Authorization/Department/Department.vue +++ b/src/views/Authorization/Department/Department.vue @@ -85,7 +85,7 @@ const crudSchemas = reactive([ table: { slots: { default: (data: any) => { - return <>{data[0].row.departmentName} + return <>{data.row.departmentName} } } }, @@ -119,7 +119,7 @@ const crudSchemas = reactive([ table: { slots: { default: (data: any) => { - const status = data[0].row.status + const status = data.row.status return ( <> @@ -215,13 +215,13 @@ const crudSchemas = reactive([ default: (data: any) => { return ( <> - action(data[0].row, 'edit')}> + action(data.row, 'edit')}> {t('exampleDemo.edit')} - action(data[0].row, 'detail')}> + action(data.row, 'detail')}> {t('exampleDemo.detail')} - delData(data[0].row)}> + delData(data.row)}> {t('exampleDemo.del')} diff --git a/src/views/Authorization/Menu/Menu.vue b/src/views/Authorization/Menu/Menu.vue index 9927185..cf43ef4 100644 --- a/src/views/Authorization/Menu/Menu.vue +++ b/src/views/Authorization/Menu/Menu.vue @@ -41,7 +41,7 @@ const tableColumns = reactive([ label: t('menu.icon'), slots: { default: (data: any) => { - const icon = data[0].row.meta.icon + const icon = data.row.meta.icon if (icon) { return ( <> @@ -59,7 +59,7 @@ const tableColumns = reactive([ label: t('menu.permission'), slots: { default: (data: any) => { - const permission = data[0].row.meta.permission + const permission = data.row.meta.permission return permission ? <>{permission.join(', ')} : null } } @@ -69,7 +69,7 @@ const tableColumns = reactive([ label: t('menu.component'), slots: { default: (data: any) => { - const component = data[0].row.component + const component = data.row.component return <>{component === '#' ? '顶级目录' : component === '##' ? '子目录' : component} } } @@ -85,8 +85,8 @@ const tableColumns = reactive([ default: (data: any) => { return ( <> - - {data[0].row.status === 1 ? t('userDemo.enable') : t('userDemo.disable')} + + {data.row.status === 1 ? t('userDemo.enable') : t('userDemo.disable')} ) @@ -99,7 +99,7 @@ const tableColumns = reactive([ width: 240, slots: { default: (data: any) => { - const row = data[0].row + const row = data.row return ( <> action(row, 'edit')}> diff --git a/src/views/Authorization/Role/Role.vue b/src/views/Authorization/Role/Role.vue index 68096af..42a7923 100644 --- a/src/views/Authorization/Role/Role.vue +++ b/src/views/Authorization/Role/Role.vue @@ -47,8 +47,8 @@ const tableColumns = reactive([ default: (data: any) => { return ( <> - - {data[0].row.status === 1 ? t('userDemo.enable') : t('userDemo.disable')} + + {data.row.status === 1 ? t('userDemo.enable') : t('userDemo.disable')} ) @@ -69,7 +69,7 @@ const tableColumns = reactive([ width: 240, slots: { default: (data: any) => { - const row = data[0].row + const row = data.row return ( <> action(row, 'edit')}> diff --git a/src/views/Authorization/User/User.vue b/src/views/Authorization/User/User.vue index 6f7720d..ccb95ca 100644 --- a/src/views/Authorization/User/User.vue +++ b/src/views/Authorization/User/User.vue @@ -150,7 +150,7 @@ const crudSchemas = reactive([ width: 240, slots: { default: (data: any) => { - const row = data[0].row as DepartmentUserItem + const row = data.row as DepartmentUserItem return ( <> action(row, 'edit')}> diff --git a/src/views/Components/Table/DefaultTable.vue b/src/views/Components/Table/DefaultTable.vue index 13a6fb0..b06eef2 100644 --- a/src/views/Components/Table/DefaultTable.vue +++ b/src/views/Components/Table/DefaultTable.vue @@ -1,7 +1,7 @@ diff --git a/src/views/Components/Table/TreeTable.vue b/src/views/Components/Table/TreeTable.vue index c97bc88..5ca4b53 100644 --- a/src/views/Components/Table/TreeTable.vue +++ b/src/views/Components/Table/TreeTable.vue @@ -1,7 +1,7 @@ diff --git a/src/views/Components/Table/UseTableDemo.vue b/src/views/Components/Table/UseTableDemo.vue index 9b78a90..78c9dbf 100644 --- a/src/views/Components/Table/UseTableDemo.vue +++ b/src/views/Components/Table/UseTableDemo.vue @@ -30,8 +30,8 @@ const columns = reactive([ field: 'expand', type: 'expand', slots: { - default: (data: TableSlotDefault[]) => { - const { row } = data[0] + default: (data: TableSlotDefault) => { + const { row } = data return (
diff --git a/src/views/Example/Dialog/ExampleDialog.vue b/src/views/Example/Dialog/ExampleDialog.vue index b544247..cec4b40 100644 --- a/src/views/Example/Dialog/ExampleDialog.vue +++ b/src/views/Example/Dialog/ExampleDialog.vue @@ -212,13 +212,13 @@ const crudSchemas = reactive([ default: (data: any) => { return ( <> - action(data[0].row, 'edit')}> + action(data.row, 'edit')}> {t('exampleDemo.edit')} - action(data[0].row, 'detail')}> + action(data.row, 'detail')}> {t('exampleDemo.detail')} - delData(data[0].row)}> + delData(data.row)}> {t('exampleDemo.del')} diff --git a/src/views/Example/Page/ExamplePage.vue b/src/views/Example/Page/ExamplePage.vue index b5db6c1..459e1b4 100644 --- a/src/views/Example/Page/ExamplePage.vue +++ b/src/views/Example/Page/ExamplePage.vue @@ -229,13 +229,13 @@ const crudSchemas = reactive([ default: (data: any) => { return ( <> - action(data[0].row, 'edit')}> + action(data.row, 'edit')}> {t('exampleDemo.edit')} - action(data[0].row, 'detail')}> + action(data.row, 'detail')}> {t('exampleDemo.detail')} - delData(data[0].row)}> + delData(data.row)}> {t('exampleDemo.del')} diff --git a/src/views/Function/MultipleTabs.vue b/src/views/Function/MultipleTabs.vue new file mode 100644 index 0000000..4c3aa93 --- /dev/null +++ b/src/views/Function/MultipleTabs.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/views/Function/MultipleTabsDemo.vue b/src/views/Function/MultipleTabsDemo.vue new file mode 100644 index 0000000..e8089bd --- /dev/null +++ b/src/views/Function/MultipleTabsDemo.vue @@ -0,0 +1,14 @@ + + + diff --git a/stylelint.config.js b/stylelint.config.js index 2acd479..de520a2 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -2,7 +2,7 @@ module.exports = { root: true, plugins: ['stylelint-order'], customSyntax: 'postcss-html', - extends: ['stylelint-config-standard', 'stylelint-config-prettier'], + extends: ['stylelint-config-standard'], rules: { 'selector-pseudo-class-no-unknown': [ true, diff --git a/vite.config.ts b/vite.config.ts index fd06ffa..86dbbcc 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -45,7 +45,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { if (name === 'click-outside') { return '' } - return `element-plus/es/components/${name.substring(3)}/style/css` + return `element-plus/es/components/${name.replace(/^el-/, '')}/style/css` } }] }),