diff --git a/.env.production b/.env.production index f02ab0b8..04dcc34e 100644 --- a/.env.production +++ b/.env.production @@ -5,7 +5,7 @@ VITE_USE_MOCK = true VITE_PUBLIC_PATH = / # 网站前缀 -VITE_BASE_URL = /naive-ui-admin-preview +VITE_BASE_URL = / # 是否删除console VITE_DROP_CONSOLE = true diff --git a/CHANGELOG.md b/CHANGELOG.md index 47da5d40..1af33567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# 1.0 (2021-07-12) +### 🐛 Bug Fixes +- 修复页面切换面包屑未及时更新 + +- ### ✨ Features +- 1.0骨架发布 +- Naive UI 升级至2.15.4 +- 菜单新增排序字段 +- 新增 `ProTable` 组件,封装了常用的分页列配置等逻辑,可查看组件示例页面 +- 持续更新中... + + # 0.1.1-beta (2021-07-07) ### 🐛 Bug Fixes - 修正黑色主题,页面背景色和导航风格问题 diff --git a/README.md b/README.md index ec8dfd41..7cd1b446 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ Naive Ui Admin 是一个免费开源的中后台模版,使用了最新的`vue3 - [ ] 监控页 - [x] 工作台 -## 预览 -- [naive-ui-admin](https://jekip.github.io/naive-ui-admin-preview) +## 在线预览 +- [naive-ui-admin](https://jekip.github.io) 账号:admin,密码:123456 diff --git a/mock/table/list.ts b/mock/table/list.ts index 48b3b253..4ccc77a1 100644 --- a/mock/table/list.ts +++ b/mock/table/list.ts @@ -28,12 +28,12 @@ export default [ timeout: 1000, method: 'get', response: ({ query }) => { - const { pageNumber = 1, pageSize = 10 } = query; + const { page = 1, pageSize = 10 } = query; const list = tableList(Number(pageSize)) return resultSuccess({ - pageNumber:Number(pageNumber), + page:Number(page), pageSize:Number(pageSize), - total: list.length, + pageCount: 60, list } ); diff --git a/package.json b/package.json index bbcbd8b0..0d0fa442 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "lodash-es": "^4.17.21", "mitt": "^2.1.0", "mockjs": "^1.1.0", - "naive-ui": "^2.15.2", + "naive-ui": "^2.15.4", "nprogress": "^1.0.0-1", "pinia": "^2.0.0-beta.3", "qs": "^6.10.1", diff --git a/src/App.vue b/src/App.vue index 7bac05bd..b24eebf9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -19,7 +19,7 @@ +``` + +API +---- +ProTable 在 NaiveUi 的 data-table 上进行了一层封装,支持了一些预设,并且封装了一些行为。这里只列出与 data-table 不同的 api。 + +> request:Promise 参考上面例子写法 +> ref:可绑定ref 调用组件内部方法(data-table本身的方法和参数) + +Methods +---- +> reload:actionRef.value.reload() + +> 其余方法,请打印查看 + +Slots +---- +> 名称:tableTitle | 表格顶部左侧区域 +> 名称:toolbar | 表格顶部右侧区域 + + +更新时间 +---- + +该文档最后更新于: 2021-07-12 PM 10:13 diff --git a/src/components/ProTable/index.ts b/src/components/ProTable/index.ts new file mode 100644 index 00000000..d8c9b566 --- /dev/null +++ b/src/components/ProTable/index.ts @@ -0,0 +1 @@ +export { default as ProTable } from './src/ProTable.vue'; diff --git a/src/components/ProTable/src/ProTable.vue b/src/components/ProTable/src/ProTable.vue new file mode 100644 index 00000000..8896be74 --- /dev/null +++ b/src/components/ProTable/src/ProTable.vue @@ -0,0 +1,296 @@ + + + + diff --git a/src/components/ProTable/src/components/settings/ColumnSetting.vue b/src/components/ProTable/src/components/settings/ColumnSetting.vue new file mode 100644 index 00000000..b7867af8 --- /dev/null +++ b/src/components/ProTable/src/components/settings/ColumnSetting.vue @@ -0,0 +1,247 @@ + + + + + diff --git a/src/components/ProTable/src/const.ts b/src/components/ProTable/src/const.ts new file mode 100644 index 00000000..c566b368 --- /dev/null +++ b/src/components/ProTable/src/const.ts @@ -0,0 +1,15 @@ +import componentSetting from '@/settings/componentSetting' + +const { table } = componentSetting + +const { apiSetting, defaultPageSize, pageSizes } = table; + +export const DEFAULTPAGESIZE = defaultPageSize; + +export const APISETTING = apiSetting; + +export const PAGESIZES = pageSizes; + + + + diff --git a/src/components/ProTable/src/hooks/useColumns.ts b/src/components/ProTable/src/hooks/useColumns.ts new file mode 100644 index 00000000..28ba90d9 --- /dev/null +++ b/src/components/ProTable/src/hooks/useColumns.ts @@ -0,0 +1,95 @@ +import { ref, Ref, ComputedRef, unref, computed, watch, toRaw } from 'vue'; +import type { BasicColumn, BasicTableProps } from '../types/table'; +import { isEqual, cloneDeep } from 'lodash-es'; +import { isArray, isString } from '@/utils/is'; + +export function useColumns(propsRef: ComputedRef) { + const columnsRef = ref(unref(propsRef).columns) as unknown as Ref; + let cacheColumns = unref(propsRef).columns; + + const getColumnsRef = computed(() => { + const columns = cloneDeep(unref(columnsRef)); + return columns; + }) + + const getPageColumns = computed(() => { + const pageColumns = unref(getColumnsRef); + const columns = cloneDeep(pageColumns); + return columns + }) + + watch( + () => unref(propsRef).columns, + (columns) => { + columnsRef.value = columns; + cacheColumns = columns?.filter((item) => !item.flag) ?? []; + } + ); + + //设置 + function setColumns(columnList: string[]) { + const columns: any[] = cloneDeep(columnList); + if (!isArray(columns)) return; + + if (!columns.length) { + columnsRef.value = []; + return; + } + const cacheKeys = cacheColumns.map((item) => item.key); + + //针对拖拽排序 + if (!isString(columns[0])) { + columnsRef.value = columns; + } else { + const newColumns: any[] = [] + cacheColumns.forEach(item => { + if (columnList.includes(item.key)) { + newColumns.push({ ...item }) + } + }) + if (!isEqual(cacheKeys, columns)) { + newColumns.sort((prev, next) => { + return ( + cacheKeys.indexOf(prev.key) - cacheKeys.indexOf(next.key) + ); + }); + } + columnsRef.value = newColumns + } + } + + //获取 + function getColumns() { + const columns = toRaw(unref(propsRef).columns); + return columns.map(item => { + return { title: item.title, key: item.key, fixed: item.fixed || undefined } + }) + } + + //获取原始 + function getCacheColumns(isKey?: boolean): any[] { + return isKey ? cacheColumns.map(item => item.key) : cacheColumns; + } + + //更新原始数据单个字段 + function setCacheColumnsField(dataIndex: string | undefined, value: Partial) { + if (!dataIndex || !value) { + return; + } + cacheColumns.forEach((item) => { + if (item.key === dataIndex) { + Object.assign(item, value); + return; + } + }); + } + + return { + getColumnsRef, + getCacheColumns, + setCacheColumnsField, + setColumns, + getColumns, + getPageColumns + }; +} diff --git a/src/components/ProTable/src/hooks/useDataSource.ts b/src/components/ProTable/src/hooks/useDataSource.ts new file mode 100644 index 00000000..7286d225 --- /dev/null +++ b/src/components/ProTable/src/hooks/useDataSource.ts @@ -0,0 +1,165 @@ +import { ref, ComputedRef, unref, computed, onMounted, onBeforeMount, watchEffect, watch } from 'vue'; +import type { BasicTableProps } from '../types/table'; +import type { PaginationProps } from '../types/pagination'; +import { isFunction, isBoolean } from '@/utils/is'; +import { DEFAULTPAGESIZE, APISETTING, PAGESIZES } from '../const'; + +export function useDataSource( + propsRef: ComputedRef, + { + getPaginationInfo, + setPagination, + setLoading, + tableData, + getSelection + }, + emit: EmitType +) { + const dataSourceRef = ref([]); + + watchEffect(() => { + tableData.value = unref(dataSourceRef); + }); + + watch( + () => unref(propsRef).dataSource, + () => { + const { dataSource }: any = unref(propsRef); + dataSource && (dataSourceRef.value = dataSource); + }, + { + immediate: true, + } + ); + + const getRowKey = computed(() => { + const { rowKey } = unref(propsRef); + return rowKey ? rowKey : () => { + return 'key' + }; + }); + + const getDataSourceRef = computed(() => { + const dataSource = unref(dataSourceRef); + if (!dataSource || dataSource.length === 0) { + return unref(dataSourceRef); + } + // if (unref(getAutoCreateKey)) { + // const firstItem = dataSource[0]; + // const lastItem = dataSource[dataSource.length - 1]; + // + // if (firstItem && lastItem) { + // if (!firstItem[ROW_KEY] || !lastItem[ROW_KEY]) { + // const data = cloneDeep(unref(dataSourceRef)); + // data.forEach((item) => { + // if (!item[ROW_KEY]) { + // item[ROW_KEY] = buildUUID(); + // } + // if (item.children && item.children.length) { + // setTableKey(item.children); + // } + // }); + // dataSourceRef.value = data; + // } + // } + // } + return unref(dataSourceRef); + }); + + async function fetch(opt?) { + try { + setLoading(true); + const { request, pagination }: any = unref(propsRef); + + //组装分页信息 + const pageField = APISETTING.pageField + const sizeField = APISETTING.sizeField + const totalField = APISETTING.totalField + const listField = APISETTING.listField + + let pageParams: Recordable = {}; + const { page = 1, pageSize = 10 } = unref(getPaginationInfo) as PaginationProps; + + if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) { + pageParams = {}; + } else { + pageParams[pageField] = (opt && opt[pageField]) || page; + pageParams[sizeField] = pageSize; + } + + let params = { + ...pageParams, + } + const res = await request(params); + + const resultTotal = res[totalField] || 0 + const currentPage = res[pageField] + + // 假如数据变少,导致总页数变少并小于当前选中页码,通过getPaginationRef获取到的页码是不正确的,需获取正确的页码再次执行 + if (resultTotal) { + const currentTotalPage = Math.ceil(resultTotal / pageSize); + if (page > currentTotalPage) { + setPagination({ + [pageField]: currentTotalPage, + }); + fetch(opt); + } + } + let resultInfo = res[listField] ? res[listField] : [] + dataSourceRef.value = resultInfo; + setPagination({ + [pageField]: currentPage, + [totalField]: resultTotal, + }); + if (opt && opt[pageField]) { + setPagination({ + [pageField]: opt[pageField] || 1, + }); + } + emit('fetch-success', { + items: unref(resultInfo), + resultTotal + }); + } catch (error) { + console.error(error) + emit('fetch-error', error); + dataSourceRef.value = []; + // setPagination({ + // pageCount: 0, + // }); + } finally { + setLoading(false); + } + } + + onMounted(() => { + setTimeout(() => { + fetch(); + }, 16) + }); + + // onBeforeMount(()=> { + // fetch() + // }) + + function setTableData(values: T[]) { + dataSourceRef.value = values; + } + + function getDataSource() { + return getDataSourceRef.value as T[]; + } + + async function reload(opt?: FetchParams) { + await fetch(opt); + } + + return { + fetch, + getRowKey, + getDataSourceRef, + getDataSource, + setTableData, + reload + } +} diff --git a/src/components/ProTable/src/hooks/useLoading.ts b/src/components/ProTable/src/hooks/useLoading.ts new file mode 100644 index 00000000..0a670b00 --- /dev/null +++ b/src/components/ProTable/src/hooks/useLoading.ts @@ -0,0 +1,21 @@ +import { ref, ComputedRef, unref, computed, watch } from 'vue'; +import type { BasicTableProps } from '../types/table'; + +export function useLoading(props: ComputedRef) { + const loadingRef = ref(unref(props).loading); + + watch( + () => unref(props).loading, + (loading) => { + loadingRef.value = loading; + } + ); + + const getLoading = computed(() => unref(loadingRef)); + + function setLoading(loading: boolean) { + loadingRef.value = loading; + } + + return { getLoading, setLoading }; +} diff --git a/src/components/ProTable/src/hooks/usePagination.ts b/src/components/ProTable/src/hooks/usePagination.ts new file mode 100644 index 00000000..899c9c51 --- /dev/null +++ b/src/components/ProTable/src/hooks/usePagination.ts @@ -0,0 +1,48 @@ +import type { PaginationProps } from '../types/pagination'; +import type { BasicTableProps } from '../types/table'; +import { computed, unref, ref, ComputedRef } from 'vue'; + +import { isBoolean } from '@/utils/is'; +import { DEFAULTPAGESIZE, PAGESIZES } from '../const'; + +export function usePagination(refProps: ComputedRef) { + const configRef = ref({}); + const show = ref(true); + + const getPaginationInfo = computed((): PaginationProps | boolean => { + const { pagination } = unref(refProps); + if (!unref(show) || (isBoolean(pagination) && !pagination)) { + return false; + } + return { + pageSize: DEFAULTPAGESIZE, + pageSizes: PAGESIZES, + showSizePicker: true, + showQuickJumper: true, + ...(isBoolean(pagination) ? {} : pagination), + ...unref(configRef), + }; + }); + + function setPagination(info: Partial) { + const paginationInfo = unref(getPaginationInfo); + configRef.value = { + ...(!isBoolean(paginationInfo) ? paginationInfo : {}), + ...info, + }; + } + + function getPagination() { + return unref(getPaginationInfo); + } + + function getShowPagination() { + return unref(show); + } + + async function setShowPagination(flag: boolean) { + show.value = flag; + } + + return { getPagination, getPaginationInfo, setShowPagination, getShowPagination, setPagination }; +} diff --git a/src/components/ProTable/src/hooks/useTableContext.ts b/src/components/ProTable/src/hooks/useTableContext.ts new file mode 100644 index 00000000..e975ac3f --- /dev/null +++ b/src/components/ProTable/src/hooks/useTableContext.ts @@ -0,0 +1,22 @@ +import type { Ref } from 'vue'; +import type { BasicTableProps, TableActionType } from '../types/table'; +import { provide, inject, ComputedRef } from 'vue'; + +const key = Symbol('s-table'); + +type Instance = TableActionType & { + wrapRef: Ref>; + getBindValues: ComputedRef; +}; + +type RetInstance = Omit & { + getBindValues: ComputedRef; +}; + +export function createTableContext(instance: Instance) { + provide(key, instance); +} + +export function useTableContext(): RetInstance { + return inject(key) as RetInstance; +} diff --git a/src/components/ProTable/src/props.ts b/src/components/ProTable/src/props.ts new file mode 100644 index 00000000..85822441 --- /dev/null +++ b/src/components/ProTable/src/props.ts @@ -0,0 +1,46 @@ +import type { PropType } from 'vue' +import { BasicColumn } from './types/table' + +export const basicProps = { + title: { + type: String, + default: null, + }, + titleTooltip: { + type: String, + default: null, + }, + size: { + type: String, + default: 'medium', + }, + tableData: { + type: [Object], + default: () => { + }, + }, + columns: { + type: [Array] as PropType, + default: () => [], + required: true, + + }, + request: { + type: Function as PropType<(...arg: any[]) => Promise>, + default: null, + required: true + }, + rowKey: { + type: [String, Function] as PropType string)>, + default: undefined, + }, + pagination: { + type: [Object, Boolean], + default: () => { + } + }, + showPagination: { + type: [String, Boolean], + default: 'auto' + } +} diff --git a/src/components/ProTable/src/types/pagination.ts b/src/components/ProTable/src/types/pagination.ts new file mode 100644 index 00000000..58a8594d --- /dev/null +++ b/src/components/ProTable/src/types/pagination.ts @@ -0,0 +1,11 @@ +import Pagination from 'naive-ui/lib/pagination'; +import { VNodeChild } from 'vue'; + +export interface PaginationProps { + page?: number; + pageCount?: number, + pageSize?: number, + pageSizes?: number[], + showSizePicker?: boolean, + showQuickJumper?: boolean, +} diff --git a/src/components/lockscreen/index.ts b/src/components/lockscreen/index.ts deleted file mode 100644 index b1187208..00000000 --- a/src/components/lockscreen/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import LockScreen from './lockscreen.vue' - -export { LockScreen } diff --git a/src/layout/components/Header/ProjectSetting.vue b/src/layout/components/Header/ProjectSetting.vue index ff8e93d9..1baac687 100644 --- a/src/layout/components/Header/ProjectSetting.vue +++ b/src/layout/components/Header/ProjectSetting.vue @@ -214,7 +214,7 @@ export default defineComponent({ watch( () => designStore.darkTheme, (to) => { - settingStore.navTheme = to ? 'header-dark': 'dark' + settingStore.navTheme = to ? 'header-dark' : 'dark' } ) diff --git a/src/layout/components/Header/index.vue b/src/layout/components/Header/index.vue index 6f83a20a..5d847507 100644 --- a/src/layout/components/Header/index.vue +++ b/src/layout/components/Header/index.vue @@ -139,7 +139,7 @@ export default defineComponent({ const getChangeStyle = computed(() => { const { collapsed } = props - const { minMenuWidth, menuWidth }:any = unref(getMenuSetting) + const { minMenuWidth, menuWidth }: any = unref(getMenuSetting) return { 'left': collapsed ? `${ minMenuWidth }px` : `${ menuWidth }px`, 'width': `calc(100% - ${ collapsed ? `${ minMenuWidth }px` : `${ menuWidth }px` })` @@ -165,7 +165,10 @@ export default defineComponent({ return currentMenu }) } - const breadcrumbList: any = generator(route.matched) + + const breadcrumbList = computed(() => { + return generator(route.matched) + }) const dropdownSelect = (key) => { router.push({ name: key }) diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue index ab4ec303..22d435a7 100644 --- a/src/layout/components/TagsView/index.vue +++ b/src/layout/components/TagsView/index.vue @@ -126,8 +126,8 @@ export default defineComponent({ const getChangeStyle = computed(() => { const { collapsed } = props const navMode = unref(getNavMode) - const { minMenuWidth, menuWidth }:any = unref(getMenuSetting) - const { fixed }:any = unref(getMultiTabsSetting) + const { minMenuWidth, menuWidth }: any = unref(getMenuSetting) + const { fixed }: any = unref(getMultiTabsSetting) let lenNum = navMode === 'horizontal' ? '0px' : collapsed ? `${ minMenuWidth }px` : `${ menuWidth }px` return { left: lenNum, @@ -545,7 +545,8 @@ export default defineComponent({ } } } -.tabs-view-default-background{ + +.tabs-view-default-background { background: #f5f7f9; } diff --git a/src/layout/index.vue b/src/layout/index.vue index b47dcee0..5a3a9825 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -13,8 +13,8 @@ :width="leftMenuWidth" :native-scrollbar="false" :inverted="inverted" class="layout-sider"> - - + + diff --git a/src/plugins/naive.ts b/src/plugins/naive.ts index a9039ffe..789d7bbe 100644 --- a/src/plugins/naive.ts +++ b/src/plugins/naive.ts @@ -8,6 +8,7 @@ import { NButton, NForm, NFormItem, + NCheckboxGroup, NCheckbox, NIcon, NLayout, @@ -57,6 +58,7 @@ const naive = create({ NButton, NForm, NFormItem, + NCheckboxGroup, NCheckbox, NIcon, NLayout, diff --git a/src/router/index.ts b/src/router/index.ts index 89a12c27..f68c9290 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -5,9 +5,10 @@ import { PageEnum } from '@/enums/pageEnum'; import { createRouterGuards } from './router-guards' import 'nprogress/css/nprogress.css' // 进度条样式 +// @ts-ignore const modules = import.meta.globEager('./modules/**/*.ts'); -const routeModuleList: AppRouteModule[] = []; +const routeModuleList: RouteRecordRaw[] = []; Object.keys(modules).forEach((key) => { const mod = modules[key].default || {}; @@ -15,7 +16,13 @@ Object.keys(modules).forEach((key) => { routeModuleList.push(...modList); }); -export const RootRoute: AppRouteRecordRaw = { +function sortRoute(a, b) { + return (a.meta.sort || 0) - (b.meta.sort || 0) +} + +routeModuleList.sort(sortRoute) + +export const RootRoute: RouteRecordRaw = { path: '/', name: 'Root', redirect: PageEnum.BASE_HOME, @@ -24,7 +31,7 @@ export const RootRoute: AppRouteRecordRaw = { }, }; -export const LoginRoute: AppRouteRecordRaw = { +export const LoginRoute: RouteRecordRaw = { path: '/login', name: 'Login', component: () => import('@/views/login/index.vue'), diff --git a/src/router/modules/comp.ts b/src/router/modules/comp.ts new file mode 100644 index 00000000..f4925bdf --- /dev/null +++ b/src/router/modules/comp.ts @@ -0,0 +1,44 @@ +import { RouteRecordRaw } from 'vue-router' +import { Layout } from '@/router/constant'; +import { ProfileOutlined } from '@vicons/antd' +import { renderIcon } from '@/utils/index' + + +const routeName = 'comp' + +/** + * @param name 路由名称, 必须设置,且不能重名 + * @param meta 路由元信息(路由附带扩展信息) + * @param redirect 重定向地址, 访问这个路由时,自定进行重定向 + * @param meta.disabled 禁用整个菜单 + * @param meta.title 菜单名称 + * @param meta.icon 菜单图标 + * @param meta.keepAlive 缓存该路由 + * @param meta.sort 排序越小越排前 + * + * */ +const routes: Array = [ + { + path: '/comp', + name: routeName, + redirect: '/comp/console', + component: Layout, + meta: { + title: '组件', + icon: renderIcon(ProfileOutlined), + sort: 1 + }, + children: [ + { + path: 'table', + name: `${ routeName }_table`, + meta: { + title: '基础表格', + }, + component: () => import('@/views/comp/table/list.vue') + } + ], + } +] + +export default routes diff --git a/src/router/modules/dashboard.ts b/src/router/modules/dashboard.ts index b0ad7cab..ba2f88b1 100644 --- a/src/router/modules/dashboard.ts +++ b/src/router/modules/dashboard.ts @@ -1,13 +1,7 @@ -import { h } from 'vue' -import { NIcon } from 'naive-ui' import { RouteRecordRaw } from 'vue-router' import { Layout } from '@/router/constant'; -import { MainView } from '@/layout/components/Main' import { DashboardOutlined } from '@vicons/antd' - -function renderIcon(icon) { - return () => h(NIcon, null, { default: () => h(icon) }) -} +import { renderIcon } from '@/utils/index' const routeName = 'dashboard' @@ -19,7 +13,7 @@ const routeName = 'dashboard' * @param meta.title 菜单名称 * @param meta.icon 菜单图标 * @param meta.keepAlive 缓存该路由 - * + * @param meta.sort 排序越小越排前 * */ const routes: Array = [ { @@ -30,7 +24,8 @@ const routes: Array = [ meta: { title: 'Dashboard', icon: renderIcon(DashboardOutlined), - permission: ['dashboard_console', 'dashboard_console', 'dashboard_workplace'] + permission: ['dashboard_console', 'dashboard_console', 'dashboard_workplace'], + sort: 0 }, children: [ { @@ -56,7 +51,7 @@ const routes: Array = [ name: `${ routeName }_workplace`, meta: { title: '工作台', - keepAlive:true, + keepAlive: true, permission: ['dashboard_workplace'] }, component: () => import('@/views/dashboard/workplace/workplace.vue') diff --git a/src/router/router-guards.ts b/src/router/router-guards.ts index 5c206b34..ab967631 100644 --- a/src/router/router-guards.ts +++ b/src/router/router-guards.ts @@ -128,7 +128,7 @@ export function createRouterGuards(router: Router) { const asyncRouteStore = useAsyncRouteStoreWidthOut(); // 在这里设置需要缓存的组件名称 const keepAliveComponents = asyncRouteStore.keepAliveComponents - const currentComName:any = to.matched.find((item) => item.name == to.name)?.name + const currentComName: any = to.matched.find((item) => item.name == to.name)?.name if (currentComName && !keepAliveComponents.includes(currentComName) && to.meta?.keepAlive) { // 需要缓存的组件 keepAliveComponents.push(currentComName) diff --git a/src/settings/componentSetting.ts b/src/settings/componentSetting.ts new file mode 100644 index 00000000..c1af7919 --- /dev/null +++ b/src/settings/componentSetting.ts @@ -0,0 +1,18 @@ +export default { + table: { + apiSetting: { + // 当前页的字段名 + pageField: 'page', + // 每页数量字段名 + sizeField: 'pageSize', + // 接口返回的数据字段名 + listField: 'list', + // 接口返回总页数字段名 + totalField: 'pageCount', + }, + //默认分页数量 + defaultPageSize: 10, + //可切换每页数量集合 + pageSizes: [10, 20, 30, 40, 50], + } +} diff --git a/src/settings/projectSetting.ts b/src/settings/projectSetting.ts index 2b550689..2e9fbd9e 100644 --- a/src/settings/projectSetting.ts +++ b/src/settings/projectSetting.ts @@ -13,7 +13,7 @@ const setting = { isReload: true }, //页脚 - showFooter:true, + showFooter: true, //多标签 multiTabsSetting: { //背景色 diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 46848ea0..e97bf3da 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -3,6 +3,7 @@ import { createStorage } from '@/utils/Storage' import { store } from '@/store' import { ACCESS_TOKEN, CURRENT_USER, IS_LOCKSCREEN } from '@/store/mutation-types' import { ResultEnum } from '@/enums/httpEnum' + const Storage = createStorage({ storage: localStorage }) import { getUserInfo, login } from '@/api/system/user' import { storage } from '@/utils/Storage' diff --git a/src/styles/common.less b/src/styles/common.less index e1fbccf2..81c3258a 100644 --- a/src/styles/common.less +++ b/src/styles/common.less @@ -94,6 +94,18 @@ body .n-card { transition: all .2s ease-in-out; } +body .proCard { + border-radius: 4px; + + .n-card__content { + padding: 16px; + + &:first-child { + padding-top: 16px; + } + } +} + .n-layout-page-header { margin: 0 -10px; } diff --git a/src/utils/index.ts b/src/utils/index.ts index 4643269f..0d912cd7 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,5 @@ import { h } from 'vue'; +import type { App, Plugin } from 'vue'; import { NIcon } from 'naive-ui' /** diff --git a/src/utils/is/index.ts b/src/utils/is/index.ts index 73ad65f1..e6732756 100644 --- a/src/utils/is/index.ts +++ b/src/utils/is/index.ts @@ -104,3 +104,11 @@ export const isServer = typeof window === 'undefined' export function isImageDom(o: Element) { return o && ['IMAGE', 'IMG'].includes(o.tagName) } + +export function isNull(val: unknown): val is null { + return val === null; +} + +export function isNullAndUnDef(val: unknown): val is null | undefined { + return isUnDef(val) && isNull(val); +} diff --git a/src/views/comp/table/columns.ts b/src/views/comp/table/columns.ts new file mode 100644 index 00000000..11d343cf --- /dev/null +++ b/src/views/comp/table/columns.ts @@ -0,0 +1,57 @@ +import { h } from 'vue' +import { NAvatar, NButton } from 'naive-ui' + +export const columns = [ + { + title: 'id', + key: 'id' + }, + { + title: '名称', + key: 'name' + }, + { + title: '头像', + key: 'avatar', + render(row) { + return h( + NAvatar, + { + size: 48, + src: row.avatar + } + ) + } + }, + { + title: '地址', + key: 'address' + }, + { + title: '开始日期', + key: 'beginTime', + }, + { + title: '结束日期', + key: 'endTime', + }, + { + title: '创建时间', + key: 'date', + }, + { + title: '操作', + key: 'actions', + render(row) { + return h( + NButton, + { + size: 'small', + onClick: () => { + } + }, + { default: () => '编辑' } + ) + } + } +] diff --git a/src/views/comp/table/list.vue b/src/views/comp/table/list.vue new file mode 100644 index 00000000..8c52d5d7 --- /dev/null +++ b/src/views/comp/table/list.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/src/views/dashboard/console/console.vue b/src/views/dashboard/console/console.vue index f5d6303c..ba9f4f37 100644 --- a/src/views/dashboard/console/console.vue +++ b/src/views/dashboard/console/console.vue @@ -13,13 +13,15 @@
- 日同比 + 日同比 +
- 周同比 + 周同比 + @@ -77,13 +79,15 @@
- 日同比 + 日同比 +
- 周同比 + 周同比 + @@ -111,13 +115,15 @@
- 月同比 + 月同比 +
- 月同比 + 月同比 + @@ -179,10 +185,10 @@ export default defineComponent({ 'border-bottom': '1px solid #eee', 'font-size': '16px' }, - visits:{}, - saleroom:{}, - orderLarge:{}, - volume:{}, + visits: {}, + saleroom: {}, + orderLarge: {}, + volume: {}, }) // 图标列表 const iconList = [ @@ -267,8 +273,8 @@ export default defineComponent({ } }, ] - onMounted(async ()=> { - const { visits, saleroom, orderLarge, volume} = await getConsoleInfo() + onMounted(async () => { + const { visits, saleroom, orderLarge, volume } = await getConsoleInfo() state.visits = visits state.saleroom = saleroom state.orderLarge = orderLarge diff --git a/src/views/dashboard/workplace/workplace.vue b/src/views/dashboard/workplace/workplace.vue index dd62ca18..83567bcc 100644 --- a/src/views/dashboard/workplace/workplace.vue +++ b/src/views/dashboard/workplace/workplace.vue @@ -41,7 +41,8 @@
-
@@ -58,7 +59,8 @@ 开源君,2021-07-04
-
@@ -75,12 +77,13 @@ 学不动也要学,2021-07-04
-
- + Html5 @@ -92,7 +95,8 @@ 撸码也是一种艺术 2021-04-01
-
@@ -109,7 +113,8 @@ 铁粉君 2021-07-04。
-
@@ -126,7 +131,8 @@ 技术牛 2021-07-04。
-
@@ -220,7 +226,9 @@ @@ -228,7 +236,8 @@ - +
@@ -327,9 +336,19 @@ import { import { defineComponent } from 'vue' export default defineComponent({ - name:'dashboard_workplace', - components: { GithubOutlined, LogoVue, DashboardOutlined, ProfileOutlined, FileProtectOutlined, SettingOutlined, ApartmentOutlined, - Html5Outlined, LogoAngular, LogoReact, LogoJavascript + name: 'dashboard_workplace', + components: { + GithubOutlined, + LogoVue, + DashboardOutlined, + ProfileOutlined, + FileProtectOutlined, + SettingOutlined, + ApartmentOutlined, + Html5Outlined, + LogoAngular, + LogoReact, + LogoJavascript }, setup() { return { @@ -342,9 +361,10 @@ export default defineComponent({ diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 7f8797ab..19583949 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -116,7 +116,7 @@ export default defineComponent({ loadingMessage = message.loading('登录中...') state.loading = true - const params:FormState = { + const params: FormState = { username, password } diff --git a/yarn.lock b/yarn.lock index e82a6db5..e44cd19b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3597,10 +3597,10 @@ mute-stream@0.0.7: resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -naive-ui@^2.15.2: - version "2.15.2" - resolved "https://registry.nlark.com/naive-ui/download/naive-ui-2.15.2.tgz#11b6504c726d33b9f95c34826de12e2739858fcd" - integrity sha1-EbZQTHJtM7n5XDSCbeEuJzmFj80= +naive-ui@^2.15.4: + version "2.15.4" + resolved "https://registry.nlark.com/naive-ui/download/naive-ui-2.15.4.tgz#56c53b03e277ac9e55396bfb85dc2b49293ca6c3" + integrity sha1-VsU7A+J3rJ5VOWv7hdwrSSk8psM= dependencies: "@css-render/plugin-bem" "^0.15.4" "@css-render/vue3-ssr" "^0.15.4"