data-table
This commit is contained in:
parent
c88d526db9
commit
590ddc8076
|
|
@ -82,7 +82,13 @@ export default [
|
|||
return true
|
||||
})
|
||||
const List = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
|
||||
return resultSuccess(List)
|
||||
const data = {
|
||||
list: List,
|
||||
page: Number(page),
|
||||
limit: Number(limit),
|
||||
total: count
|
||||
}
|
||||
return resultSuccess(data)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
"@vicons/antd": "^0.10.0",
|
||||
"@vicons/ionicons5": "^0.10.0",
|
||||
"axios": "^0.26.1",
|
||||
"dayjs": "^1.11.0",
|
||||
"mockjs": "^1.1.0",
|
||||
"pinia": "^2.0.13",
|
||||
"vue": "^3.2.16",
|
||||
|
|
|
|||
|
|
@ -13,27 +13,78 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="s-table">
|
||||
<n-data-table v-bind="getBindProps" />
|
||||
<n-data-table
|
||||
ref="tableElRef"
|
||||
v-bind="getBindProps"
|
||||
:pagination="pagination"
|
||||
@update:page="updatePage"
|
||||
@update:page-size="updatePageSize"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NDataTable } from 'naive-ui'
|
||||
import { unref, computed } from 'vue'
|
||||
import { tableProps } from './tools/props.js'
|
||||
import { useDataSource } from './tools/useDataSource.js'
|
||||
import { usePagination } from './tools/usePagination.js'
|
||||
import { ref, unref, computed, toRaw, provide } from 'vue'
|
||||
export default {
|
||||
name: 'DataTable',
|
||||
props: {
|
||||
...NDataTable.props
|
||||
...tableProps
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const getProps = computed(() => {
|
||||
return { ...props }
|
||||
})
|
||||
|
||||
/* loading--start */
|
||||
const loadingRef = ref(unref(getProps).loading)
|
||||
const getLoading = computed(() => unref(loadingRef))
|
||||
function setLoading(loading) {
|
||||
loadingRef.value = loading
|
||||
}
|
||||
/* loading--end */
|
||||
|
||||
/* pagination-start */
|
||||
const { getPaginationInfo, setPagination } = usePagination(getProps)
|
||||
const pagination = computed(() => toRaw(unref(getPaginationInfo)))
|
||||
|
||||
/* 页码切换 */
|
||||
function updatePage(page) {
|
||||
setPagination({ page: page })
|
||||
reload()
|
||||
}
|
||||
|
||||
/* 分页数量切换 */
|
||||
function updatePageSize(size) {
|
||||
setPagination({ page: 1, pageSize: size })
|
||||
reload()
|
||||
}
|
||||
/* pagination-end */
|
||||
|
||||
/* tableData-start */
|
||||
const tableData = ref([])
|
||||
const { getDataSourceRef, getRowKey, reload } = useDataSource(getProps, { getPaginationInfo, setPagination, tableData, setLoading }, emit)
|
||||
const getBindProps = computed(() => {
|
||||
return {
|
||||
...unref(props)
|
||||
...unref(getProps),
|
||||
loading: unref(getLoading),
|
||||
rowKey: unref(getRowKey),
|
||||
data: unref(getDataSourceRef),
|
||||
remote: true
|
||||
}
|
||||
})
|
||||
console.log(getBindProps)
|
||||
|
||||
const key = Symbol('s-table')
|
||||
provide(key, { getBindProps })
|
||||
/* tableData-end */
|
||||
|
||||
return {
|
||||
getBindProps
|
||||
getBindProps,
|
||||
pagination,
|
||||
updatePage,
|
||||
updatePageSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import { NDataTable } from 'naive-ui'
|
||||
|
||||
export const tableProps = {
|
||||
...NDataTable.props,
|
||||
/* 初始化接口请求 */
|
||||
request: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
/* 分页信息 */
|
||||
pagination: {
|
||||
type: [Object, Boolean],
|
||||
default: () => {}
|
||||
},
|
||||
/* 分页设置信息 */
|
||||
paginationSetting: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
// 当前页的字段名
|
||||
pageField: 'page',
|
||||
// 每页数量字段名
|
||||
sizeField: 'limit',
|
||||
// 接口返回的数据字段名
|
||||
listField: 'list',
|
||||
// 接口返回总页数字段名
|
||||
totalField: 'total',
|
||||
// 默认分页数量
|
||||
pageSize: 10,
|
||||
// 可切换每页数量集合
|
||||
pageSizes: [10, 20, 30, 40, 50],
|
||||
// 是否显示每页条数的选择器
|
||||
showSizePicker: false,
|
||||
// 是否显示快速跳转
|
||||
showQuickJumper: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
import { ref, unref, computed, onMounted } from 'vue'
|
||||
import { isBoolean } from '@/utils/is'
|
||||
|
||||
export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) {
|
||||
const dataSourceRef = ref([])
|
||||
|
||||
async function fetch(opt) {
|
||||
try {
|
||||
/* 设置loading */
|
||||
setLoading(true)
|
||||
const { request, pagination, paginationSetting } = unref(propsRef)
|
||||
/* 无接口请求中断 */
|
||||
if (!request) return
|
||||
/* 获取分页信息 */
|
||||
const pageField = paginationSetting.pageField
|
||||
const sizeField = paginationSetting.sizeField
|
||||
const totalField = paginationSetting.totalField
|
||||
const listField = paginationSetting.listField
|
||||
|
||||
let pageParams = {}
|
||||
const { page = 1, pageSize = 10 } = unref(getPaginationInfo)
|
||||
/* 判断是否需要分页信息 */
|
||||
if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) {
|
||||
pageParams = {}
|
||||
} else {
|
||||
pageParams[pageField] = (opt && opt[pageField]) || page
|
||||
pageParams[sizeField] = pageSize
|
||||
}
|
||||
const params = {
|
||||
...pageParams
|
||||
}
|
||||
const response = await request(params)
|
||||
const res = response.data
|
||||
const resultTotal = res[totalField] || 0
|
||||
const currentPage = res[pageField]
|
||||
// 如果数据异常,需获取正确的页码再次执行
|
||||
if (resultTotal) {
|
||||
if (page > Math.ceil(resultTotal / pageSize)) {
|
||||
setPagination({
|
||||
[pageField]: Math.ceil(resultTotal / pageSize)
|
||||
})
|
||||
fetch(opt)
|
||||
}
|
||||
}
|
||||
const resultInfo = res[listField] ? res[listField] : []
|
||||
dataSourceRef.value = resultInfo
|
||||
setPagination({
|
||||
[pageField]: currentPage,
|
||||
[totalField]: Math.ceil(resultTotal / pageSize)
|
||||
})
|
||||
/* 更新页码数据 */
|
||||
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 = []
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const getDataSourceRef = computed(() => {
|
||||
const dataSource = unref(dataSourceRef)
|
||||
if (!dataSource || dataSource.length === 0) {
|
||||
return unref(dataSourceRef)
|
||||
}
|
||||
return unref(dataSourceRef)
|
||||
})
|
||||
|
||||
function getDataSource() {
|
||||
return getDataSourceRef.value
|
||||
}
|
||||
|
||||
function setTableData(values) {
|
||||
dataSourceRef.value = values
|
||||
}
|
||||
|
||||
const getRowKey = computed(() => {
|
||||
const { rowKey } = unref(propsRef)
|
||||
return rowKey || (() => {
|
||||
return 'key'
|
||||
})
|
||||
})
|
||||
|
||||
async function reload(opt) {
|
||||
await fetch(opt)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
fetch()
|
||||
}, 15)
|
||||
})
|
||||
|
||||
return {
|
||||
fetch,
|
||||
getDataSourceRef,
|
||||
getDataSource,
|
||||
setTableData,
|
||||
getRowKey,
|
||||
reload
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { computed, unref, ref } from 'vue'
|
||||
import { isBoolean } from '@/utils/is'
|
||||
|
||||
export function usePagination(refProps) {
|
||||
const configRef = ref({})
|
||||
const getPaginationInfo = computed(() => {
|
||||
const { pagination, paginationSetting } = unref(refProps)
|
||||
/* 判断是否需要展示分页 */
|
||||
if ((isBoolean(pagination) && !pagination)) {
|
||||
return false
|
||||
}
|
||||
/* 返回配置的分页信息 */
|
||||
return {
|
||||
pageSize: paginationSetting.pageSize,
|
||||
pageSizes: paginationSetting.pageSizes,
|
||||
showSizePicker: paginationSetting.showSizePicker,
|
||||
showQuickJumper: paginationSetting.showQuickJumper,
|
||||
...(isBoolean(pagination) ? {} : pagination),
|
||||
...unref(configRef),
|
||||
pageCount: unref(configRef)[paginationSetting.totalField]
|
||||
}
|
||||
})
|
||||
|
||||
function setPagination(info) {
|
||||
const paginationInfo = unref(getPaginationInfo)
|
||||
configRef.value = {
|
||||
...(!isBoolean(paginationInfo) ? paginationInfo : {}),
|
||||
...info
|
||||
}
|
||||
}
|
||||
|
||||
function getPagination() {
|
||||
return unref(getPaginationInfo)
|
||||
}
|
||||
|
||||
return { getPaginationInfo, setPagination, getPagination }
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<div class="tabs-view" :class="{'tabs-view-fix': tagsMenuSetting.fixed,}">
|
||||
<div class="tabs-view" :class="{'tabs-view-fix': tagsMenuSetting.fixed,}" :style="getChangeStyle">
|
||||
<div class="tabs-view-main">
|
||||
<div ref="navWrap" class="tabs-card" :class="{ 'tabs-card-scrollable': scrollable }">
|
||||
<span class="tabs-card-prev" :class="{ 'tabs-card-prev-hide': !scrollable }" @click="scrollPrev">
|
||||
<div ref="navWrap" class="tabs-card" :class="{ 'tabs-card-scrollable': state.scrollable }">
|
||||
<span class="tabs-card-prev" :class="{ 'tabs-card-prev-hide': !state.scrollable }" @click="scrollPrev">
|
||||
<n-icon size="16" color="#515a6e">
|
||||
<LeftOutlined />
|
||||
</n-icon>
|
||||
</span>
|
||||
<span class="tabs-card-next" :class="{ 'tabs-card-next-hide': !scrollable }" @click="scrollNext">
|
||||
<span class="tabs-card-next" :class="{ 'tabs-card-next-hide': !state.scrollable }" @click="scrollNext">
|
||||
<n-icon size="16" color="#515a6e">
|
||||
<RightOutlined />
|
||||
</n-icon>
|
||||
|
|
@ -31,6 +31,31 @@
|
|||
</Draggable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabs-close">
|
||||
<n-dropdown
|
||||
trigger="hover"
|
||||
placement="bottom-end"
|
||||
:options="tagsMemuOptions"
|
||||
@select="closeHandleSelect"
|
||||
>
|
||||
<div class="tabs-close-btn">
|
||||
<n-icon size="16" color="#515a6e">
|
||||
<DownOutlined />
|
||||
</n-icon>
|
||||
</div>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
|
||||
<n-dropdown
|
||||
:show="state.showDropdown"
|
||||
:x="state.dropdownX"
|
||||
:y="state.dropdownY"
|
||||
placement="bottom-start"
|
||||
:options="tagsMemuOptions"
|
||||
@clickoutside="onClickOutside"
|
||||
@select="closeHandleSelect"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -39,26 +64,59 @@
|
|||
import {
|
||||
LeftOutlined,
|
||||
RightOutlined,
|
||||
CloseOutlined
|
||||
CloseOutlined,
|
||||
DownOutlined,
|
||||
ReloadOutlined,
|
||||
ColumnWidthOutlined,
|
||||
MinusOutlined
|
||||
} from '@vicons/antd'
|
||||
import Draggable from 'vuedraggable'
|
||||
import { reactive, computed, watch } from 'vue'
|
||||
import { reactive, computed, watch, defineProps, ref, unref, provide, nextTick } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useTagsMenuStore } from '@/store/modules/tagsMenu.js'
|
||||
import { useSettingStore } from '@/store/modules/setting.js'
|
||||
import { getTags, setTags } from '@/utils/tags.js'
|
||||
import { isString } from '@/utils/is.js'
|
||||
import { renderIcon } from '@/utils'
|
||||
|
||||
const props = defineProps({
|
||||
collapsed: {
|
||||
type: Boolean
|
||||
},
|
||||
menuMode: {
|
||||
type: String,
|
||||
default: 'sidebar'
|
||||
}
|
||||
})
|
||||
|
||||
/* 白名单 */
|
||||
const whiteList = ['Login', 'NOT_FOUND']
|
||||
/* 基础页面 */
|
||||
const baseMenu = '/home'
|
||||
|
||||
/* 获取路由器 */
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { push, replace } = router
|
||||
|
||||
/* 使用store数据 */
|
||||
const tagsMenuStore = useTagsMenuStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const tabsList = computed(() => tagsMenuStore.tabsList)
|
||||
const tagsMenuSetting = computed(() => settingStore.getTagsMenuSetting)
|
||||
|
||||
/* 组装样式 */
|
||||
const getChangeStyle = computed(() => {
|
||||
const { collapsed, menuMode } = props
|
||||
const { cWidth, width } = unref(settingStore.getSidebarSetting)
|
||||
const { fixed } = unref(settingStore.getTagsMenuSetting)
|
||||
const lenNum = menuMode === 'header' ? '0px' : collapsed ? `${cWidth}px` : `${width}px`
|
||||
return {
|
||||
left: lenNum,
|
||||
width: `calc(100% - ${!fixed ? '0px' : lenNum})`
|
||||
}
|
||||
})
|
||||
|
||||
let cacheRoutes = []
|
||||
const simpleRoute = getSimpleRoute(route)
|
||||
try {
|
||||
|
|
@ -82,13 +140,15 @@ tagsMenuStore.initTabs(cacheRoutes)
|
|||
|
||||
const state = reactive({
|
||||
activeKey: route.fullPath,
|
||||
scrollable: false
|
||||
scrollable: false,
|
||||
showDropdown: false,
|
||||
dropdownX: 0,
|
||||
dropdownY: 0
|
||||
})
|
||||
|
||||
watch(
|
||||
() => route.fullPath,
|
||||
(to) => {
|
||||
console.log('to', to)
|
||||
// if (whiteList.includes(route.name)) return
|
||||
state.activeKey = to
|
||||
tagsMenuStore.addTabs(getSimpleRoute(route))
|
||||
|
|
@ -143,27 +203,147 @@ function goPage(e) {
|
|||
* @description: 删除项
|
||||
* @return {*}
|
||||
*/
|
||||
// 删除tab
|
||||
function closeTabItem(e) {
|
||||
// const { fullPath } = e
|
||||
// const routeInfo = tabsList.value.find((item) => item.fullPath == fullPath)
|
||||
// removeTab(routeInfo)
|
||||
const { fullPath } = e
|
||||
const routeInfo = tabsList.value.find((item) => item.fullPath === fullPath)
|
||||
removeTab(routeInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description:
|
||||
* @return {*}
|
||||
*/
|
||||
|
||||
const removeTab = (route) => {
|
||||
if (tabsList.value.length === 1) {
|
||||
// return message.warning('这已经是最后一页,不能再关闭了!')
|
||||
}
|
||||
// delKeepAliveCompName()
|
||||
tagsMenuStore.closeCurrentTab(route)
|
||||
// 如果关闭的是当前页
|
||||
if (state.activeKey === route.fullPath) {
|
||||
const currentRoute = tabsList.value[Math.max(0, tabsList.value.length - 1)]
|
||||
state.activeKey = currentRoute.fullPath
|
||||
router.push(currentRoute)
|
||||
}
|
||||
// updateNavScroll()
|
||||
}
|
||||
|
||||
// const delKeepAliveCompName = () => {
|
||||
// if (route.meta.keepAlive) {
|
||||
// const name = router.currentRoute.value.matched.find((item) => item.name === route.name)
|
||||
// ?.components?.default.name
|
||||
// if (name) {
|
||||
// asyncRouteStore.keepAliveComponents = asyncRouteStore.keepAliveComponents.filter(
|
||||
// (item) => item != name
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/* dropdown--start */
|
||||
/* 右侧下拉菜单 */
|
||||
const isCurrent = ref(false)
|
||||
const tagsMemuOptions = computed(() => {
|
||||
const isDisabled = unref(tabsList).length <= 1
|
||||
return [
|
||||
{
|
||||
label: '刷新当前',
|
||||
key: '1',
|
||||
icon: renderIcon(ReloadOutlined)
|
||||
},
|
||||
{
|
||||
label: `关闭当前`,
|
||||
key: '2',
|
||||
disabled: unref(isCurrent) || isDisabled,
|
||||
icon: renderIcon(CloseOutlined)
|
||||
},
|
||||
{
|
||||
label: '关闭其他',
|
||||
key: '3',
|
||||
disabled: isDisabled,
|
||||
icon: renderIcon(ColumnWidthOutlined)
|
||||
},
|
||||
{
|
||||
label: '关闭全部',
|
||||
key: '4',
|
||||
disabled: isDisabled,
|
||||
icon: renderIcon(MinusOutlined)
|
||||
}
|
||||
]
|
||||
})
|
||||
/* 操作右侧下拉菜单 */
|
||||
const closeHandleSelect = (key) => {
|
||||
switch (key) {
|
||||
// 刷新
|
||||
case '1':
|
||||
reloadPage()
|
||||
break
|
||||
// 关闭
|
||||
case '2':
|
||||
removeTab(route)
|
||||
break
|
||||
// 关闭其他
|
||||
case '3':
|
||||
closeOther(route)
|
||||
break
|
||||
// 关闭所有
|
||||
case '4':
|
||||
closeAll()
|
||||
break
|
||||
}
|
||||
// updateNavScroll()
|
||||
state.showDropdown = false
|
||||
}
|
||||
/* 刷新页面 */
|
||||
const reloadPage = () => {
|
||||
// delKeepAliveCompName()
|
||||
router.push({
|
||||
path: '/redirect' + unref(route).fullPath
|
||||
})
|
||||
}
|
||||
/* 注入刷新页面方法 */
|
||||
provide('reloadPage', reloadPage)
|
||||
/* 关闭其他 */
|
||||
const closeOther = (route) => {
|
||||
tagsMenuStore.closeOtherTabs(route)
|
||||
state.activeKey = route.fullPath
|
||||
router.replace(route.fullPath)
|
||||
// updateNavScroll()
|
||||
}
|
||||
|
||||
/* 关闭全部 */
|
||||
const closeAll = () => {
|
||||
tagsMenuStore.closeAllTabs()
|
||||
router.replace(baseMenu)
|
||||
// updateNavScroll()
|
||||
}
|
||||
/* dropdown--end */
|
||||
/* contextMenu--start */
|
||||
/**
|
||||
* @description: 右键菜单
|
||||
* @return {*}
|
||||
*/
|
||||
function handleContextMenu(e, item) {
|
||||
// e.preventDefault()
|
||||
// isCurrent.value = PageEnum.BASE_HOME_REDIRECT === item.path
|
||||
// state.showDropdown = false
|
||||
// nextTick().then(() => {
|
||||
// state.showDropdown = true
|
||||
// state.dropdownX = e.clientX
|
||||
// state.dropdownY = e.clientY
|
||||
// })
|
||||
e.preventDefault()
|
||||
isCurrent.value = baseMenu === item.path
|
||||
state.showDropdown = false
|
||||
nextTick().then(() => {
|
||||
state.showDropdown = true
|
||||
state.dropdownX = e.clientX
|
||||
state.dropdownY = e.clientY
|
||||
})
|
||||
}
|
||||
|
||||
function onClickOutside() {
|
||||
state.showDropdown = false
|
||||
}
|
||||
/* contextMenu--end */
|
||||
/**
|
||||
* @description: 页面跳转
|
||||
* @param undefined
|
||||
* @param undefined
|
||||
* @return {*}
|
||||
*/
|
||||
function go(opt, isReplace = false) {
|
||||
if (!opt) {
|
||||
return
|
||||
|
|
@ -258,6 +438,24 @@ function go(opt, isReplace = false) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-close {
|
||||
min-width: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
// background: var(--color);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
.tabs-close-btn {
|
||||
// color: var(--color);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-view-fix {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useUserStore } from '@/store/modules/user'
|
||||
import { usePermissionStore } from '@/store/modules/permission'
|
||||
import { NOT_FOUND_ROUTE } from '@/router/routes'
|
||||
import { NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes'
|
||||
import { getToken } from '@/utils/token'
|
||||
|
||||
const WHITE_LIST = ['/login', '/redirect']
|
||||
|
|
@ -14,7 +14,6 @@ export function createPermissionGuard(router) {
|
|||
next({ path: '/' })
|
||||
} else {
|
||||
const hasRoutes = !!permissionStore.permissionRoutes.length
|
||||
console.log(permissionStore.permissionRoutes)
|
||||
if (hasRoutes) {
|
||||
next()
|
||||
} else {
|
||||
|
|
@ -23,6 +22,7 @@ export function createPermissionGuard(router) {
|
|||
const routes = await permissionStore.generateRoutes()
|
||||
router.addRoute(routes[0])
|
||||
router.addRoute(NOT_FOUND_ROUTE)
|
||||
router.addRoute(REDIRECT_ROUTE)
|
||||
next({ ...to, replace: true })
|
||||
} catch (error) {
|
||||
// removeToken()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ export const basicRoutes = [
|
|||
name: 'Home',
|
||||
component: Home,
|
||||
meta: {
|
||||
title: '首页'
|
||||
title: '首页',
|
||||
affix: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -39,6 +40,27 @@ export const NOT_FOUND_ROUTE = {
|
|||
isHidden: true
|
||||
}
|
||||
|
||||
export const REDIRECT_ROUTE = {
|
||||
path: '/redirect',
|
||||
name: 'Redirect',
|
||||
component: Layout,
|
||||
meta: {
|
||||
title: 'Redirect',
|
||||
hideBreadcrumb: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/redirect/:path(.*)',
|
||||
name: 'Redirect',
|
||||
component: () => import('@/views/redirect/index.vue'),
|
||||
meta: {
|
||||
title: 'Redirect',
|
||||
hideBreadcrumb: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const modules = import.meta.globEager('./modules/*.js')
|
||||
const asyncRoutes = []
|
||||
Object.keys(modules).forEach((key) => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { h } from 'vue'
|
||||
import { NIcon } from 'naive-ui'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
/**
|
||||
|
|
@ -74,3 +76,11 @@ export function debounce(method, wait, immediate) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 渲染图标
|
||||
* @return {*}
|
||||
*/
|
||||
export function renderIcon(icon) {
|
||||
return () => h(NIcon, null, { default: () => h(icon) })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
import { defineComponent, onBeforeMount } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RedirectPage',
|
||||
setup() {
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
onBeforeMount(() => {
|
||||
const { params, query } = route
|
||||
const { path } = params
|
||||
router.replace({
|
||||
path: '/' + (Array.isArray(path) ? path.join('/') : path),
|
||||
query
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
@ -1,19 +1,20 @@
|
|||
<template>
|
||||
<div>
|
||||
<data-table :columns="data.columns" :data="data.data" size="large">
|
||||
<template #tableTitle>
|
||||
<n-button type="primary">
|
||||
添加角色
|
||||
</n-button>
|
||||
</template>
|
||||
</data-table>
|
||||
|
||||
<n-card>
|
||||
<data-table :columns="data.columns" :pagination="false" :data="data.data" size="large">
|
||||
<template #tableTitle>
|
||||
<n-button type="primary">
|
||||
添加角色
|
||||
</n-button>
|
||||
</template>
|
||||
</data-table>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataTable from '@/components/DataTable/index.vue'
|
||||
import Action from '@/components/DataTable/tools/action.vue'
|
||||
import Action from '@/components/DataTable/tools/Action.vue'
|
||||
import { getMenuList } from '@/api/system/index.js'
|
||||
import { h, onMounted } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
|
|
|
|||
|
|
@ -1,17 +1,181 @@
|
|||
<template>
|
||||
<div>
|
||||
1
|
||||
<n-card>
|
||||
<data-table
|
||||
:columns="data.columns"
|
||||
:row-key="(row) => row.id"
|
||||
:request="loadDataTable"
|
||||
size="large"
|
||||
scroll-x="1200"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary">
|
||||
新建
|
||||
</n-button>
|
||||
<n-button type="primary">
|
||||
删除
|
||||
</n-button>
|
||||
</template>
|
||||
</data-table>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataTable from '@/components/DataTable/index.vue'
|
||||
import TableAction from '@/components/DataTable/tools/Action.vue'
|
||||
import TableImage from '@/components/DataTable/tools/Image.vue'
|
||||
import { getUserList } from '@/api/system/index.js'
|
||||
import { h, onMounted, unref } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
export default {
|
||||
name: '',
|
||||
name: 'MenuPage',
|
||||
components: { dataTable },
|
||||
setup() {
|
||||
const data = reactive({
|
||||
columns: [
|
||||
{
|
||||
title: '用户编号',
|
||||
key: 'code',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
align: 'center',
|
||||
render(row) {
|
||||
return h(TableImage, {
|
||||
images: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
src: row.avatar
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '用户账号',
|
||||
key: 'username',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户姓名',
|
||||
key: 'realname',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '用户类型',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
key: 'roles',
|
||||
align: 'center'
|
||||
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
key: 'deptName',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
key: 'updateTime',
|
||||
align: 'center',
|
||||
width: 160
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
fixed: 'right',
|
||||
render(row) {
|
||||
return h(TableAction, {
|
||||
actions: [
|
||||
{
|
||||
label: '添加',
|
||||
type: 'button',
|
||||
props: {
|
||||
type: 'primary',
|
||||
onClick: play.bind(null, row)
|
||||
},
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '修改',
|
||||
auth: 'basic_list'
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'popconfirm',
|
||||
auth: 'basic_list'
|
||||
}
|
||||
],
|
||||
align: 'center'
|
||||
})
|
||||
}
|
||||
}
|
||||
],
|
||||
data: [],
|
||||
pagination: {
|
||||
pageSize: 10
|
||||
}
|
||||
})
|
||||
|
||||
function play(row) {
|
||||
console.log(row)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 获取用户数据
|
||||
* @return {*}
|
||||
*/
|
||||
async function fetchList() {
|
||||
const params = {
|
||||
page: 1,
|
||||
limit: 10
|
||||
}
|
||||
const res = await getUserList(params)
|
||||
data.data = res.data
|
||||
}
|
||||
|
||||
const params = reactive({
|
||||
name: 'xiaoMa'
|
||||
})
|
||||
|
||||
const loadDataTable = async(res) => {
|
||||
const _params = {
|
||||
...unref(params),
|
||||
...res
|
||||
}
|
||||
return await getUserList(_params)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchList()
|
||||
})
|
||||
|
||||
return { data, loadDataTable }
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
.n-button+.n-button{
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue