mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-04-05 06:34:12 +08:00
version: v4.9.3
This commit is contained in:
parent
3f7e3722fd
commit
fa8d52601f
25
CHANGELOG.md
25
CHANGELOG.md
@ -1,5 +1,30 @@
|
||||
# CHANGE LOG
|
||||
|
||||
## 4.9.3
|
||||
|
||||
## Feats
|
||||
|
||||
- 更新 `vue` 版本至 `3.4.38`
|
||||
- 更新 `vite` 版本至 `5.4.1`
|
||||
- 调整 `RCollapseGrid` 支持 `actionAlign` 配置型,配置按钮垂直方向,默认为 `end`
|
||||
- `MenuTag` 组件
|
||||
- 调整 `MenuTag` 滚动条样式,现在将它隐藏了
|
||||
- 优化关闭按钮样式
|
||||
- `RTable` 新增 `renderWrapperHeader` 配置项,配置外层容器 `header` 是否渲染
|
||||
- `postcss` 配置 `not dead`,忽略兼容已经无需兼容的浏览器
|
||||
- `RChart` 组件 `setOptions` 方法配置项默认不启用 `merge` 模式
|
||||
- 调整 `header` 的样式,增加了一点点间隙
|
||||
- `useDevice` 新增 `observer` 配置项,可以自定义观察回调
|
||||
- 新增 `components-pro` 包,助力简化业务开发
|
||||
- 新增 `RTablePro` 组件,大幅简化中后台带有过滤请求条件的表格显示业务
|
||||
- 新增 `RCollapse` 组件,允许折叠过滤条件
|
||||
|
||||
## Fixes
|
||||
|
||||
- 移除 `postcss-px-to-viewport-8-plugin` 插件,使用 `postcss-px-to-viewport-8-with-include` 替换,修复 `include` 失效问题
|
||||
- 修复 `useElementFullscreen` 在退出时,没有正确的回滚 `zIndex` 的问题
|
||||
- 修复 `RChart` 配置 `setChartOptions` 不生效的问题
|
||||
|
||||
## 4.9.2
|
||||
|
||||
## Feats
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ray-template",
|
||||
"private": false,
|
||||
"version": "4.9.2",
|
||||
"version": "4.9.3",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": "^18.0.0 || >=20.0.0",
|
||||
@ -48,7 +48,7 @@
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.0",
|
||||
"print-js": "^1.6.0",
|
||||
"vue": "^3.4.34",
|
||||
"vue": "^3.4.38",
|
||||
"vue-demi": "0.14.6",
|
||||
"vue-hooks-plus": "2.2.1",
|
||||
"vue-i18n": "^9.13.1",
|
||||
@ -85,14 +85,14 @@
|
||||
"husky": "8.0.3",
|
||||
"lint-staged": "^15.1.0",
|
||||
"postcss": "^8.4.31",
|
||||
"postcss-px-to-viewport-8-plugin": "1.2.3",
|
||||
"postcss-px-to-viewport-8-with-include": "1.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "1.71.1",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"typescript": "^5.2.2",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.3.5",
|
||||
"vite": "^5.4.1",
|
||||
"vite-bundle-analyzer": "0.9.4",
|
||||
"vite-plugin-cdn2": "1.1.0",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
|
521
pnpm-lock.yaml
generated
521
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -8,31 +8,32 @@ module.exports = {
|
||||
'ff > 31',
|
||||
'ie >= 8',
|
||||
'last 10 versions',
|
||||
'not dead',
|
||||
],
|
||||
grid: true,
|
||||
},
|
||||
// 为了适配 postcss8.x 版本的转换库
|
||||
'postcss-px-to-viewport-8-plugin': {
|
||||
inlinePxToViewport: true,
|
||||
/** 视窗的宽度(设计稿的宽度) */
|
||||
'postcss-px-to-viewport-8-with-include': {
|
||||
// 横屏时使用的视口宽度
|
||||
landscapeWidth: 1920,
|
||||
// 视窗的宽度(设计稿的宽度)
|
||||
viewportWidth: 1920,
|
||||
/** 视窗的高度(设计稿高度, 一般无需指定) */
|
||||
viewportHeight: 1080,
|
||||
/** 指定 px 转换为视窗单位值的小数位数 */
|
||||
// 指定 px 转换为视窗单位值的小数位数
|
||||
unitPrecision: 3,
|
||||
/** 指定需要转换成的视窗单位 */
|
||||
viewportUnit: 'rem',
|
||||
/** 制定字体转换单位 */
|
||||
fontViewportUnit: 'rem',
|
||||
/** 指定不转换为视窗单位的类 */
|
||||
// 指定需要转换成的视窗单位
|
||||
viewportUnit: 'vw',
|
||||
// 制定字体转换单位
|
||||
fontViewportUnit: 'vw',
|
||||
// 指定不转换为视窗单位的类
|
||||
selectorBlackList: ['.ignore'],
|
||||
/** 小于或等于 1px 不转换为视窗单位 */
|
||||
// 小于或等于 1px 不转换为视窗单位
|
||||
minPixelValue: 1,
|
||||
/** 允许在媒体查询中转换 px */
|
||||
// 允许在媒体查询中转换 px
|
||||
mediaQuery: false,
|
||||
exclude: /(\/|\\)(node_modules)(\/|\\)/, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
|
||||
include: [/^src[/\\].*\.(vue|tsx|jsx|ts(?!d))$/],
|
||||
preserve: true,
|
||||
// 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
|
||||
exclude: /node_modules/,
|
||||
// 指定一个空的文件夹,避免影响到无需转换的文件
|
||||
include: [],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
49
src/components-pro/RCollapse/Collapse.tsx
Normal file
49
src/components-pro/RCollapse/Collapse.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
*
|
||||
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||
*
|
||||
* @date 2024-05-16
|
||||
*
|
||||
* @workspace ray-template
|
||||
*
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import { RCollapseGrid, RForm } from '@/components'
|
||||
|
||||
import { collapseGridProps, formProps } from '@/components'
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 基于 RCollapseGrid 和 RForm 的折叠表单组件;
|
||||
* 同样也继承了 RCollapseGrid 组件的缺点,必须使用 NFormItemGi, NGridItem 组件包裹表单项。
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'RCollapse',
|
||||
props: Object.assign(
|
||||
{},
|
||||
{
|
||||
...collapseGridProps,
|
||||
open: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
cols: {
|
||||
type: Number,
|
||||
default: 4,
|
||||
},
|
||||
},
|
||||
formProps,
|
||||
),
|
||||
render() {
|
||||
const { $slots, $props } = this
|
||||
const { labelPlacement, showFeedback, ...rest } = $props
|
||||
|
||||
return (
|
||||
<RForm {...rest} labelPlacement="top" showFeedback={false}>
|
||||
<RCollapseGrid {...rest}>{$slots}</RCollapseGrid>
|
||||
</RForm>
|
||||
)
|
||||
},
|
||||
})
|
11
src/components-pro/RTablePro/index.ts
Normal file
11
src/components-pro/RTablePro/index.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import RTablePro from './src/TablePro'
|
||||
import tableProProps from './src/props'
|
||||
import { useTablePro } from './src/hooks/useTablePro'
|
||||
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
|
||||
type TableProProps = ExtractPropTypes<typeof tableProProps>
|
||||
|
||||
export type { TableProProps }
|
||||
|
||||
export { RTablePro, useTablePro, tableProProps }
|
179
src/components-pro/RTablePro/src/TablePro.tsx
Normal file
179
src/components-pro/RTablePro/src/TablePro.tsx
Normal file
@ -0,0 +1,179 @@
|
||||
/**
|
||||
*
|
||||
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||
*
|
||||
* @date 2024-05-10
|
||||
*
|
||||
* @workspace ray-template
|
||||
*
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import { RTable } from '@/components'
|
||||
|
||||
import props from './props'
|
||||
import { useTable } from '@/components'
|
||||
import { call } from '@/utils'
|
||||
import { usePagination } from '@/hooks'
|
||||
|
||||
import type { TablePagination, TableRequestConfig, TableProInst } from './types'
|
||||
import type { Recordable } from '@/types'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RTablePro',
|
||||
props,
|
||||
setup(props) {
|
||||
const [register, { getTableInstance }] = useTable()
|
||||
const [
|
||||
paginationRef,
|
||||
{
|
||||
getPage,
|
||||
getPageSize,
|
||||
setCallback,
|
||||
setItemCount,
|
||||
getPagination,
|
||||
resetPagination,
|
||||
getItemCount,
|
||||
},
|
||||
] = usePagination(void 0, {
|
||||
prefix: (info) => `共 ${info.itemCount} 条`,
|
||||
})
|
||||
const tableRequestRef = computed(() => props.request)
|
||||
|
||||
// 获取最新 statistics 和 pagination 值
|
||||
const update = (): TablePagination => {
|
||||
const pagination = getPagination()
|
||||
|
||||
return {
|
||||
getItemCount,
|
||||
getPage,
|
||||
getPageSize,
|
||||
}
|
||||
}
|
||||
|
||||
// 派发表格更新事件
|
||||
const emitTableUpdate = () => {
|
||||
const { onTablePaginationUpdate } = props
|
||||
|
||||
if (onTablePaginationUpdate) {
|
||||
call(onTablePaginationUpdate, update())
|
||||
}
|
||||
}
|
||||
|
||||
// 合并请求参数
|
||||
const combineRequestParams = (extraConfig?: TableRequestConfig) => {
|
||||
const config = Object.assign({}, props.requestConfig, extraConfig)
|
||||
|
||||
const { params, formatRangeTime } = config
|
||||
|
||||
// 转换时间范围,该功能仅支持 NDatePicker range 模式参数
|
||||
if (formatRangeTime?.length && params) {
|
||||
formatRangeTime.forEach((curr) => {
|
||||
const { key, target } = curr
|
||||
const val = params[key] as [number, number] | null
|
||||
|
||||
if (val && target?.length) {
|
||||
const [start, end] = val
|
||||
|
||||
params[target[0]] = start
|
||||
params[target[1]] = end
|
||||
} else {
|
||||
// 当传递时间参数被清空时,则清空对应 time key
|
||||
params[key] = null
|
||||
params[target[0]] = null
|
||||
params[target[1]] = null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const requestParams = Object.assign({}, params, {
|
||||
page: getPage(),
|
||||
pageSize: getPageSize(),
|
||||
})
|
||||
|
||||
return requestParams
|
||||
}
|
||||
|
||||
// 会重置 pagination 的请求
|
||||
const runResetPaginationRequest = (extraConfig?: TableRequestConfig) => {
|
||||
resetPagination()
|
||||
|
||||
const requestParams = combineRequestParams(extraConfig)
|
||||
|
||||
tableRequestRef.value?.(requestParams)
|
||||
}
|
||||
|
||||
// 不会重置 pagination 的请求
|
||||
const runRequest = (extraConfig?: TableRequestConfig) => {
|
||||
const requestParams = combineRequestParams(extraConfig)
|
||||
|
||||
tableRequestRef.value?.(requestParams)
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
setItemCount(props.paginationCount)
|
||||
setCallback(() => {
|
||||
const { manual } = props
|
||||
|
||||
if (!manual) {
|
||||
runRequest()
|
||||
}
|
||||
|
||||
emitTableUpdate()
|
||||
})
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const { onRegister } = props
|
||||
|
||||
if (onRegister && getTableInstance()) {
|
||||
const {
|
||||
clearFilters,
|
||||
clearSorter,
|
||||
downloadCsv,
|
||||
filters,
|
||||
page,
|
||||
scrollTo,
|
||||
sort,
|
||||
filter,
|
||||
print,
|
||||
} = getTableInstance()
|
||||
|
||||
call(onRegister, {
|
||||
getTablePagination: update,
|
||||
runTableRequest: runResetPaginationRequest,
|
||||
clearFilters,
|
||||
clearSorter,
|
||||
downloadCsv,
|
||||
filters,
|
||||
page,
|
||||
scrollTo,
|
||||
sort,
|
||||
filter,
|
||||
print,
|
||||
getCurrentTableRequestParams:
|
||||
combineRequestParams as TableProInst['getCurrentTableRequestParams'],
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
register,
|
||||
paginationRef,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { register, $props, paginationRef, $slots } = this
|
||||
const { onRegister, showPagination, ...rest } = $props
|
||||
|
||||
return (
|
||||
<RTable
|
||||
{...rest}
|
||||
onRegister={register}
|
||||
pagination={showPagination ? paginationRef : void 0}
|
||||
>
|
||||
{$slots}
|
||||
</RTable>
|
||||
)
|
||||
},
|
||||
})
|
172
src/components-pro/RTablePro/src/hooks/useTablePro.ts
Normal file
172
src/components-pro/RTablePro/src/hooks/useTablePro.ts
Normal file
@ -0,0 +1,172 @@
|
||||
import type { Recordable } from '@/types'
|
||||
import type { TableProInst, TableRequestConfig } from '../types'
|
||||
import type {
|
||||
RTableInst,
|
||||
CsvOptionsType,
|
||||
FilterState,
|
||||
ScrollToOptions,
|
||||
ColumnKey,
|
||||
SortOrder,
|
||||
} from '@/components/RTable/src/types'
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 获取 TablePro 实例上的一些方法。
|
||||
* 使用方法与 useTable 类似。
|
||||
*/
|
||||
export const useTablePro = () => {
|
||||
const tableInst = ref<TableProInst>()
|
||||
|
||||
const register = (inst: TableProInst) => {
|
||||
if (inst) {
|
||||
tableInst.value = inst
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 获取 TablePro 实例。
|
||||
*/
|
||||
const getTableProInstance = () => {
|
||||
if (!tableInst.value) {
|
||||
throw new Error(
|
||||
'[useTablePro]: table instance is not ready yet. if you are using useTablePro, please make sure you have called register method in onRegister event.',
|
||||
)
|
||||
}
|
||||
|
||||
return tableInst.value
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 获取 statistics, pagination 更新信息。
|
||||
*/
|
||||
const getTablePagination = () =>
|
||||
getTableProInstance().getTablePagination.call(null)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 手动触发表格请求,用于手动刷新表格。
|
||||
* 如果设置了 manual 为 true,则需要手动调用该函数。
|
||||
* 该函数会自动匹配 statistics, pagination 更新的值去请求。
|
||||
*
|
||||
* 允许手动配置 TableRequestConfig 参数,会自动合并 props tableRequestConfig 配置。
|
||||
* 并且,运行该函数会重置 pagination 为初始状态。
|
||||
*/
|
||||
const runTableRequest = <T extends Recordable>(
|
||||
extraConfig?: TableRequestConfig<T>,
|
||||
) => getTableProInstance().runTableRequest.call(null, extraConfig)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 清空所有 filter 状态。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#filter-and-sorter
|
||||
*/
|
||||
const clearFilters = () => getTableProInstance().clearFilters.call(null)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 清空所有 sort 状态。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#filter-and-sorter
|
||||
*/
|
||||
const clearSorter = () => getTableProInstance().clearSorter.call(null)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 下载 CSV。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#export-csv.vue
|
||||
*/
|
||||
const downloadCsv = (options?: CsvOptionsType) =>
|
||||
getTableProInstance().downloadCsv.call(null, options)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 设定表格当前的过滤器。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#filter-and-sorter
|
||||
*/
|
||||
const filters = (filters: FilterState | null) =>
|
||||
getTableProInstance().filters.call(null, filters)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 手动设置 page。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#DataTable-Methods
|
||||
*/
|
||||
const page = (page: number) => getTableProInstance().page.call(null, page)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 滚动内容。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#DataTable-Methods
|
||||
*/
|
||||
const scrollTo: ScrollToOptions = (options) =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
getTableProInstance().scrollTo(options as any)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 设定表格的过滤状态。
|
||||
*
|
||||
* @see https://www.naiveui.com/zh-CN/dark/components/data-table#DataTable-Methods
|
||||
*/
|
||||
const sort = (columnKey: ColumnKey, order: SortOrder) =>
|
||||
getTableProInstance().sort.call(null, columnKey, order)
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 打印表格。
|
||||
*/
|
||||
const print = () => getTableProInstance().print.call(null)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param extraConfig 额外请求合并配置项
|
||||
*
|
||||
* @description
|
||||
* 获取当前内部表格请求参数。
|
||||
*/
|
||||
const getCurrentTableRequestParams = <T = Recordable>(
|
||||
extraConfig?: TableRequestConfig<T>,
|
||||
): T & Recordable =>
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
getTableProInstance().getCurrentTableRequestParams.call(null, extraConfig)
|
||||
|
||||
return [
|
||||
register,
|
||||
{
|
||||
clearFilters,
|
||||
getTableProInstance,
|
||||
clearSorter,
|
||||
downloadCsv,
|
||||
filters,
|
||||
page,
|
||||
scrollTo,
|
||||
sort,
|
||||
getTablePagination,
|
||||
runTableRequest,
|
||||
print,
|
||||
getCurrentTableRequestParams,
|
||||
},
|
||||
] as const
|
||||
}
|
||||
|
||||
export type UseTableProReturn = ReturnType<typeof useTablePro>
|
106
src/components-pro/RTablePro/src/props.ts
Normal file
106
src/components-pro/RTablePro/src/props.ts
Normal file
@ -0,0 +1,106 @@
|
||||
import { tableProps } from '@/components'
|
||||
import { omit } from 'lodash-es'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
import type { TableProInst, TablePagination, TableRequestConfig } from './types'
|
||||
import type { AnyFC } from '@/types'
|
||||
|
||||
const props = {
|
||||
...omit(tableProps, ['pagination']),
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 分页总数。
|
||||
*
|
||||
* @default 1
|
||||
*/
|
||||
paginationCount: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 注册 useTablePro 钩子函数。
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
onRegister: {
|
||||
type: Function as PropType<(inst: TableProInst) => void>,
|
||||
default: void 0,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 是否需要手动控制表格的刷新。
|
||||
* 如果设置为 true,在 Pagination 更新时,不会自动触发表格的刷新。
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
manual: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 刷新表格的请求函数。
|
||||
* 该属性用于配置表格的刷新请求函数。
|
||||
*
|
||||
* 如果设置了该属性,则会在表格刷新时调用该函数。
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
request: {
|
||||
type: Function as PropType<AnyFC>,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* pagination 更新时的回调函数。
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
onTablePaginationUpdate: {
|
||||
type: Function as PropType<(pagination: TablePagination) => void>,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 请求函数的参数。
|
||||
* 该属性用于配置请求函数的参数。
|
||||
*
|
||||
* @default {}
|
||||
*/
|
||||
requestConfig: {
|
||||
type: Object as PropType<TableRequestConfig>,
|
||||
default: () => ({}),
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 是否显示分页器。
|
||||
* 如果需要显示分页器,则设置为 true。
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
showPagination: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 设置表格数据为异步状态。
|
||||
* 当你使用该组件的时候,会默认认为你总是异步获取数据,所以重写了原组件的 remote,
|
||||
* 现在 remote 默认为开启状态,也就是默认为 true。
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
remote: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
}
|
||||
|
||||
export default props
|
75
src/components-pro/RTablePro/src/types.ts
Normal file
75
src/components-pro/RTablePro/src/types.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import type { TableProps, RTableInst } from '@/components'
|
||||
import type { UsePaginationReturn } from '@/hooks'
|
||||
import type { Recordable } from '@/types'
|
||||
|
||||
export type FormatRangeTime = {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 请求参数中需要格式化的时间参数字段。
|
||||
*/
|
||||
key: string | number
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 后端接口中需要的起止时间参数字段。
|
||||
*/
|
||||
target: [string | number, string | number]
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* Pagination 分页配置。
|
||||
*/
|
||||
export type TablePagination = Pick<
|
||||
UsePaginationReturn[1],
|
||||
'getItemCount' | 'getPage' | 'getPageSize'
|
||||
>
|
||||
|
||||
export interface TableRequestConfig<Params = Recordable> {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 请求参数。
|
||||
* @default undefined
|
||||
*/
|
||||
params?: Params
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 格式化时间范围,该字段用于格式化时间范围。
|
||||
* 并且仅支持 NDatePicker range 模式。
|
||||
* 如果在请求的参数中,有时间段的字段,且需要格式化时间段,则需要配置该字段。
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
formatRangeTime?: FormatRangeTime[]
|
||||
}
|
||||
|
||||
export type TableProProps = Omit<TableProps, 'pagination'>
|
||||
|
||||
export interface TableProInst extends Omit<RTableInst, 'getTableInstance'> {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 获取 pagination 更新值。
|
||||
*/
|
||||
getTablePagination: () => TablePagination
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 手动触发表格请求,用于手动刷新表格。
|
||||
*/
|
||||
runTableRequest: (extraConfig?: TableRequestConfig) => void
|
||||
/**
|
||||
*
|
||||
* @param extraConfig 额外请求合并配置项
|
||||
*
|
||||
* @description
|
||||
* 获取当前内部表格请求参数。
|
||||
*/
|
||||
getCurrentTableRequestParams: <T = Recordable>(
|
||||
extraConfig?: TableRequestConfig<T>,
|
||||
) => TableRequestConfig<T>['params'] & Recordable
|
||||
}
|
4
src/components-pro/index.ts
Normal file
4
src/components-pro/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import RCollapse from './RCollapse/Collapse'
|
||||
|
||||
export * from './RTablePro'
|
||||
export { RCollapse }
|
@ -48,7 +48,7 @@ import type { DropdownProps, DropdownOption } from 'naive-ui'
|
||||
|
||||
// setOption 默认配置项
|
||||
const defaultChartOptions = {
|
||||
notMerge: false,
|
||||
notMerge: true,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
replaceMerge: [],
|
||||
@ -434,8 +434,8 @@ export default defineComponent({
|
||||
const options = combineChartOptions(ndata)
|
||||
const setOpt = Object.assign(
|
||||
{},
|
||||
props.setChartOptions,
|
||||
defaultChartOptions,
|
||||
props.setChartOptions,
|
||||
)
|
||||
|
||||
// 如果 options 发生变动更新 echarts
|
||||
|
@ -356,12 +356,12 @@ const props = {
|
||||
* @description
|
||||
* 设置 setOptions 方法配置项。
|
||||
*
|
||||
* @default {notMerge:false,lazyUpdate:true,silent:false,replaceMerge:[]}
|
||||
* @default {notMerge:true,lazyUpdate:true,silent:false,replaceMerge:[]}
|
||||
*/
|
||||
setChartOptions: {
|
||||
type: Object as PropType<SetOptionOpts>,
|
||||
default: () => ({
|
||||
notMerge: false,
|
||||
notMerge: true,
|
||||
lazyUpdate: true,
|
||||
silent: false,
|
||||
replaceMerge: [],
|
||||
|
@ -20,4 +20,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ray-collapse-grid__suffix--btn {
|
||||
align-self: var(--r-collapse-grid-action-align);
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,13 @@ export default defineComponent({
|
||||
props,
|
||||
setup(props) {
|
||||
const modelCollapsed = ref(!props.open)
|
||||
const cssVars = computed(() => {
|
||||
const cssVar = {
|
||||
'--r-collapse-grid-action-align': props.actionAlign,
|
||||
}
|
||||
|
||||
return cssVar
|
||||
})
|
||||
|
||||
const collapseClick = () => {
|
||||
modelCollapsed.value = !modelCollapsed.value
|
||||
@ -68,11 +75,14 @@ export default defineComponent({
|
||||
modelCollapsed,
|
||||
collapseClick,
|
||||
CollapseIcon,
|
||||
cssVars,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { cssVars } = this
|
||||
|
||||
return (
|
||||
<NCard bordered={this.bordered}>
|
||||
<NCard bordered={this.bordered} style={[cssVars]}>
|
||||
{{
|
||||
default: () => (
|
||||
<NGrid
|
||||
@ -84,7 +94,7 @@ export default defineComponent({
|
||||
collapsedRows={this.collapsedRows}
|
||||
>
|
||||
{this.$slots.default?.()}
|
||||
<NGridItem suffix class="ray-collapse-grid__suffix--btn">
|
||||
<NGridItem suffix class={['ray-collapse-grid__suffix--btn']}>
|
||||
<NFlex justify="end" align="center">
|
||||
{this.$slots.action?.()}
|
||||
{this.CollapseIcon()}
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { gridProps } from 'naive-ui'
|
||||
|
||||
import type { PropType } from 'vue'
|
||||
import type { CollapseToggleText } from './types'
|
||||
import type { CollapseToggleText, ActionAlignType } from './types'
|
||||
import type { AnyFC, MaybeArray } from '@/types'
|
||||
|
||||
const props = {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 自定义操作按钮区域按钮列排列方式。
|
||||
*
|
||||
* @default end
|
||||
*/
|
||||
actionAlign: {
|
||||
type: String as PropType<ActionAlignType>,
|
||||
default: 'end',
|
||||
},
|
||||
open: {
|
||||
/**
|
||||
*
|
||||
|
@ -1 +1,3 @@
|
||||
export type CollapseToggleText = [string | number, string | number]
|
||||
|
||||
export type ActionAlignType = 'auto' | 'end' | 'center' | 'start'
|
||||
|
@ -25,8 +25,6 @@ const useModal = () => {
|
||||
},
|
||||
trigger: 'none',
|
||||
style: {
|
||||
padding:
|
||||
'0 var(--n-padding-left) var(--n-padding-bottom) var(--n-padding-left)',
|
||||
width: 'auto',
|
||||
height:
|
||||
'calc(100vh - 29px - var(--n-padding-bottom) - var(--n-padding-bottom) - var(--n-padding-top))',
|
||||
|
@ -25,7 +25,11 @@ import { pick } from 'lodash-es'
|
||||
|
||||
import type { DropdownOption, DataTableInst } from 'naive-ui'
|
||||
import type { ComponentSize } from '@/types'
|
||||
import type { C as CType, PropsComponentPopselectKeys } from './types'
|
||||
import type {
|
||||
C as CType,
|
||||
PropsComponentPopselectKeys,
|
||||
RTableInst,
|
||||
} from './types'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'RTable',
|
||||
@ -34,7 +38,7 @@ export default defineComponent({
|
||||
setup(props, ctx) {
|
||||
const { expose, emit } = ctx
|
||||
|
||||
const rTableInst = ref<DataTableInst>()
|
||||
const rTableInst = ref<RTableInst>()
|
||||
const wrapperRef = ref<HTMLElement>()
|
||||
|
||||
const uuidWrapper = uuid(16) // wrapper id
|
||||
@ -147,7 +151,7 @@ export default defineComponent({
|
||||
const { toolOptions } = props
|
||||
|
||||
return toolOptions
|
||||
?.filter(() => Boolean)
|
||||
?.filter(Boolean)
|
||||
.map((curr) => (typeof curr === 'function' ? curr() : curr))
|
||||
}
|
||||
|
||||
@ -251,6 +255,7 @@ export default defineComponent({
|
||||
title,
|
||||
$slots,
|
||||
propsPopselectValue,
|
||||
renderWrapperHeader,
|
||||
} = this
|
||||
const { class: className } = $attrs
|
||||
const { tool, combineRowProps, contextMenuSelect } = this
|
||||
@ -299,9 +304,11 @@ export default defineComponent({
|
||||
) : null}
|
||||
</>
|
||||
),
|
||||
header: renderNode(title, {
|
||||
header: renderWrapperHeader
|
||||
? renderNode(title, {
|
||||
defaultElement: <div style="display: none;"></div>,
|
||||
}),
|
||||
})
|
||||
: null,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
'header-extra': tool($props as any),
|
||||
footer: () => $slots.tableFooter?.(),
|
||||
|
@ -280,7 +280,7 @@ const useCheckedRowKeys = <
|
||||
* 选中指定的 keys。
|
||||
* 当你调用该方法时,会将 keys 与 data 中的 rows 进行比对,将匹配的 rows 添加到已选中的 rows 中。
|
||||
*
|
||||
* 如果 multiple 为 false,那么只会选中一个 key;
|
||||
* 如果 multiple 为 false,那么只会选中一个 key;重复的选择,将会以最后一次绑定的 key 为准。
|
||||
* 所以,如果你需要选中多个 key,需要将 multiple 设置为 true。
|
||||
*/
|
||||
const selectKey = (key: RowKey) => {
|
||||
|
@ -61,7 +61,6 @@ const useTable = () => {
|
||||
'[useTable]: table instance is not ready yet. if you are using useTable, please make sure you have called register method in onRegister event.',
|
||||
)
|
||||
}
|
||||
console.log(tableRef.value)
|
||||
|
||||
return tableRef.value
|
||||
}
|
||||
|
@ -25,6 +25,18 @@ import type { Recordable } from '@/types'
|
||||
|
||||
const props = {
|
||||
...dataTableProps,
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 是否渲染外层容器 header,默认渲染。
|
||||
* 如果配置为 false,则不会显示外层容器的头部。
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
renderWrapperHeader: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
|
@ -47,7 +47,14 @@ export interface C extends DataTableBaseColumn {
|
||||
children?: C[]
|
||||
}
|
||||
|
||||
export interface RTableInst extends Omit<DataTableInst, 'clearFilter'> {}
|
||||
export interface RTableInst extends Omit<DataTableInst, 'clearFilter'> {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 打印表格。
|
||||
*/
|
||||
print: () => void
|
||||
}
|
||||
|
||||
export type OverridesTableColumn<T = Recordable> = C | DataTableColumn<T>
|
||||
|
||||
|
@ -33,6 +33,13 @@ export interface UseDeviceOptions extends UseWindowSizeOptions {
|
||||
* @default 768
|
||||
*/
|
||||
media?: number
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 当尺寸更新后的回调函数。
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
observer?: Callback
|
||||
}
|
||||
|
||||
@ -72,7 +79,7 @@ export function useDevice(options?: UseDeviceOptions) {
|
||||
width,
|
||||
height,
|
||||
isTabletOrSmaller: readonly(isTabletOrSmaller),
|
||||
}
|
||||
} as const
|
||||
}
|
||||
|
||||
export type UseDeviceReturnType = ReturnType<typeof useDevice>
|
||||
|
@ -196,6 +196,9 @@ export const useElementFullscreen = (
|
||||
element.removeAttribute(ID_TAG)
|
||||
}
|
||||
|
||||
// 回滚 z-index 值,避免无限增加
|
||||
currentZIndex--
|
||||
|
||||
stopWatch()
|
||||
})
|
||||
|
||||
|
@ -55,7 +55,8 @@ $menuTagWrapperWidth: 76px;
|
||||
opacity: 0;
|
||||
|
||||
& .ray-icon {
|
||||
transform: translate(-1px, 0px);
|
||||
width: 11px !important;
|
||||
height: 11px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +71,9 @@ $menuTagWrapperWidth: 76px;
|
||||
padding: 1px;
|
||||
transition: all 0.3s var(--r-bezier);
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -490,6 +490,10 @@ export default defineComponent({
|
||||
{...{
|
||||
id: uuidScrollBar,
|
||||
}}
|
||||
themeOverrides={{
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
}}
|
||||
>
|
||||
<NFlex
|
||||
ref="menuTagSpaceRef"
|
||||
|
@ -162,7 +162,7 @@ export default defineComponent({
|
||||
))}
|
||||
{getBreadcrumbSwitch ? <Breadcrumb /> : null}
|
||||
</NFlex>
|
||||
<NFlex justify="end" align="center" size={[0, 0]} wrap={false}>
|
||||
<NFlex justify="end" align="center" size={[4, 0]} wrap={false}>
|
||||
{isRenderVNode(
|
||||
<GlobalSearchButton
|
||||
onClick={(e) => {
|
||||
|
@ -27,5 +27,6 @@
|
||||
"SvgIcon": "SVG Icon",
|
||||
"Table": "Table",
|
||||
"TemplateHooks": "Template Api",
|
||||
"scrollReveal": "Scroll Reveal"
|
||||
"scrollReveal": "Scroll Reveal",
|
||||
"TablePro": "Table Pro"
|
||||
}
|
||||
|
@ -27,5 +27,6 @@
|
||||
"SvgIcon": "SVG 图标",
|
||||
"Table": "表格",
|
||||
"TemplateHooks": "模板内置 Api",
|
||||
"scrollReveal": "滚动动画"
|
||||
"scrollReveal": "滚动动画",
|
||||
"TablePro": "高级表格"
|
||||
}
|
||||
|
19
src/router/modules/demo/table-pro.ts
Normal file
19
src/router/modules/demo/table-pro.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { t } from '@/hooks/web/useI18n'
|
||||
import { LAYOUT } from '@/router/constant'
|
||||
|
||||
import type { AppRouteRecordRaw } from '@/router/types'
|
||||
|
||||
const r: AppRouteRecordRaw = {
|
||||
path: '/table-pro',
|
||||
component: () => import('@/views/demo/TablePro'),
|
||||
meta: {
|
||||
i18nKey: t('menu.TablePro'),
|
||||
icon: 'other',
|
||||
order: 2,
|
||||
extra: {
|
||||
label: 'TablePro',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default r
|
470
src/views/demo/TablePro.tsx
Normal file
470
src/views/demo/TablePro.tsx
Normal file
@ -0,0 +1,470 @@
|
||||
/**
|
||||
*
|
||||
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||
*
|
||||
* @date 2024-08-23
|
||||
*
|
||||
* @workspace ray-template
|
||||
*
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import { RTablePro, RCollapse } from '@/components-pro'
|
||||
import {
|
||||
NFlex,
|
||||
NTag,
|
||||
NButton,
|
||||
NFormItemGi,
|
||||
NInput,
|
||||
NCard,
|
||||
NRadioGroup,
|
||||
NRadioButton,
|
||||
NFormItem,
|
||||
NSelect,
|
||||
NDatePicker,
|
||||
} from 'naive-ui'
|
||||
|
||||
import { uuid } from '@/utils'
|
||||
import { useHookPlusRequest } from '@/axios'
|
||||
import Mock from 'mockjs'
|
||||
import dayjs from 'dayjs'
|
||||
import { useTablePro } from '@/components-pro'
|
||||
import { useCheckedRowKeys } from '@/components'
|
||||
import { useDayjs } from '@/hooks'
|
||||
|
||||
import type { DataTableColumns } from 'naive-ui'
|
||||
|
||||
type RowData = {
|
||||
key: number | string
|
||||
name: string
|
||||
age: number
|
||||
address: string
|
||||
tags: string[]
|
||||
remark: string
|
||||
status: string
|
||||
statusText: string
|
||||
signTimeEnd: number
|
||||
signTimeStart: number
|
||||
}
|
||||
|
||||
interface ParamsRef
|
||||
extends Partial<
|
||||
Pick<RowData, 'name' | 'status' | 'signTimeStart' | 'signTimeEnd'>
|
||||
> {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
RangeTime?: [number, number] | null
|
||||
}
|
||||
|
||||
interface BasicResponse<T = unknown> {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 返回数据。
|
||||
*/
|
||||
data: T
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 返回描述信息。
|
||||
*/
|
||||
message: string
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 返回状态码。
|
||||
*/
|
||||
code: number
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 额外的错误描述信息。
|
||||
*/
|
||||
exceptionMessage: string
|
||||
}
|
||||
|
||||
interface PaginationResponse<T = unknown> extends BasicResponse<T> {
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 分页总条数。
|
||||
*/
|
||||
total: number
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 分页页数。
|
||||
*/
|
||||
pageSize: number
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* 当前页数。
|
||||
*/
|
||||
page: number
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TableProDemo',
|
||||
setup() {
|
||||
const { format } = useDayjs()
|
||||
|
||||
/**
|
||||
*
|
||||
* @description
|
||||
* register: 注册表格实例
|
||||
* runTableRequest: 获取 TablePro 内部管理的请求方法,会自动合并 page, pageSize 等参数,如果有。
|
||||
* getUpdateInfo: 如果需要自定义请求情况,可以使用该方法获取最新的 page, pageSize 等参数。
|
||||
*/
|
||||
const [
|
||||
tableProRegister,
|
||||
{ runTableRequest, getCurrentTableRequestParams, print, downloadCsv },
|
||||
] = useTablePro()
|
||||
// 表格数据
|
||||
const tableDataRef = ref<RowData[]>([])
|
||||
// 表格列
|
||||
const baseColumns: DataTableColumns<RowData> = [
|
||||
{
|
||||
type: 'selection',
|
||||
},
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: 'Sign Status',
|
||||
key: 'statusText',
|
||||
},
|
||||
{
|
||||
title: 'Sign Time',
|
||||
key: 'signTimeStart',
|
||||
render: (row: RowData) =>
|
||||
format(row.signTimeStart) + ' ~ ' + format(row.signTimeEnd),
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
key: 'age',
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
key: 'address',
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
||||
key: 'tags',
|
||||
render: (row: RowData) => {
|
||||
const tags = row.tags.map((tagKey) => {
|
||||
return (
|
||||
<NTag type="info" bordered={false} style="margin-right: 6px">
|
||||
{tagKey}
|
||||
</NTag>
|
||||
)
|
||||
})
|
||||
|
||||
return tags
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Remark',
|
||||
key: 'remark',
|
||||
},
|
||||
]
|
||||
// 表格分页数据
|
||||
const itemCountRef = ref(0)
|
||||
// 查询条件
|
||||
const conditionRef = ref<ParamsRef>({})
|
||||
// 缓存模拟数据,不用关心
|
||||
const mockPersonList = ref<RowData[]>(
|
||||
(() => {
|
||||
const length = 30
|
||||
const list: RowData[] = []
|
||||
const time = dayjs().valueOf()
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
list.push({
|
||||
key: uuid(),
|
||||
name: Mock.Random.cname(),
|
||||
age: i + 20,
|
||||
address: Mock.Random.city(),
|
||||
tags: ['nice', 'developer'],
|
||||
remark: '我是一条很长很长的备注',
|
||||
status: i % 2 === 0 ? 'success' : 'error',
|
||||
statusText: i % 2 === 0 ? '在线' : '离线',
|
||||
signTimeStart: dayjs(time)
|
||||
.add(i * 2, 'year')
|
||||
.valueOf(),
|
||||
signTimeEnd: dayjs(time)
|
||||
.add(i + 5, 'day')
|
||||
.valueOf(),
|
||||
})
|
||||
}
|
||||
|
||||
return list
|
||||
})(),
|
||||
)
|
||||
const radioRef = ref({
|
||||
pagination: true,
|
||||
manual: false,
|
||||
})
|
||||
const [
|
||||
checkedRowKeys,
|
||||
{ checkedRowKeysBind, getKeys, getRows, clearKey, clearAll, selectKey },
|
||||
] = useCheckedRowKeys(tableDataRef, baseColumns, {
|
||||
rowKey: 'key',
|
||||
onChange: (keys, rows, meta) => {},
|
||||
})
|
||||
|
||||
const isNullOrUndefined = (value: unknown) => {
|
||||
return value === null || value === void 0
|
||||
}
|
||||
|
||||
// 模拟请求
|
||||
const getPersonList = (
|
||||
params: ParamsRef,
|
||||
): Promise<PaginationResponse<RowData[]>> => {
|
||||
return new Promise((resolve) => {
|
||||
const {
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
name,
|
||||
status,
|
||||
signTimeStart,
|
||||
signTimeEnd,
|
||||
} = params || {}
|
||||
let list: RowData[] = mockPersonList.value
|
||||
const defaultLength = mockPersonList.value.length
|
||||
|
||||
if (name) {
|
||||
list = list.filter((curr) => curr.name.includes(name))
|
||||
}
|
||||
|
||||
if (status) {
|
||||
list = list.filter((curr) => curr.status === status)
|
||||
}
|
||||
|
||||
if (signTimeStart && signTimeEnd) {
|
||||
list = list.filter((curr) => {
|
||||
return (
|
||||
curr.signTimeStart >= signTimeStart &&
|
||||
curr.signTimeEnd <= signTimeEnd
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
list = list.slice((page - 1) * pageSize, page * pageSize)
|
||||
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
code: 0,
|
||||
data: list,
|
||||
total:
|
||||
isNullOrUndefined(status) &&
|
||||
isNullOrUndefined(name) &&
|
||||
(isNullOrUndefined(signTimeStart) ||
|
||||
isNullOrUndefined(signTimeEnd))
|
||||
? defaultLength
|
||||
: list.length,
|
||||
message: 'success',
|
||||
page,
|
||||
pageSize,
|
||||
} as PaginationResponse<RowData[]>)
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
const { run: runGetPersonList, loading: loadingGetPersonList } =
|
||||
useHookPlusRequest(getPersonList, {
|
||||
onSuccess: (res) => {
|
||||
const { data, total } = res
|
||||
|
||||
tableDataRef.value = data
|
||||
itemCountRef.value = total
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
tableDataRef,
|
||||
baseColumns,
|
||||
itemCountRef,
|
||||
loadingGetPersonList,
|
||||
runGetPersonList,
|
||||
conditionRef,
|
||||
radioRef,
|
||||
runTableRequest,
|
||||
tableProRegister,
|
||||
print,
|
||||
downloadCsv,
|
||||
checkedRowKeysBind,
|
||||
checkedRowKeys,
|
||||
getKeys,
|
||||
getRows,
|
||||
clearKey,
|
||||
clearAll,
|
||||
selectKey,
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
tableDataRef,
|
||||
baseColumns,
|
||||
itemCountRef,
|
||||
loadingGetPersonList,
|
||||
runGetPersonList,
|
||||
conditionRef,
|
||||
radioRef,
|
||||
runTableRequest,
|
||||
tableProRegister,
|
||||
print,
|
||||
downloadCsv,
|
||||
checkedRowKeysBind,
|
||||
getKeys,
|
||||
getRows,
|
||||
clearKey,
|
||||
clearAll,
|
||||
selectKey,
|
||||
} = this
|
||||
|
||||
return (
|
||||
<NFlex vertical>
|
||||
<RCollapse>
|
||||
{{
|
||||
default: () => (
|
||||
<>
|
||||
<NFormItemGi label="用户名">
|
||||
<NInput v-model:value={conditionRef.name} clearable />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="状态">
|
||||
<NSelect
|
||||
v-model:value={conditionRef.status}
|
||||
clearable
|
||||
options={[
|
||||
{
|
||||
label: '成功',
|
||||
value: 'success',
|
||||
},
|
||||
{
|
||||
label: '失败',
|
||||
value: 'error',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="登陆时间">
|
||||
<NDatePicker
|
||||
type="datetimerange"
|
||||
v-model:value={conditionRef.RangeTime}
|
||||
clearable
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi label="演示折叠的条件框">
|
||||
<NInput readonly placeholder="我只是为了占位" />
|
||||
</NFormItemGi>
|
||||
</>
|
||||
),
|
||||
action: () => (
|
||||
<NFlex>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => runTableRequest()}
|
||||
loading={loadingGetPersonList}
|
||||
>
|
||||
查询
|
||||
</NButton>
|
||||
</NFlex>
|
||||
),
|
||||
}}
|
||||
</RCollapse>
|
||||
<NCard title="常用高级拓展功能">
|
||||
<NFlex>
|
||||
<NFormItem label="分页">
|
||||
<NRadioGroup v-model:value={radioRef.pagination}>
|
||||
<NRadioButton value={true}>显示分页</NRadioButton>
|
||||
<NRadioButton value={false}>隐藏分页</NRadioButton>
|
||||
</NRadioGroup>
|
||||
</NFormItem>
|
||||
<NFormItem label="自动更新">
|
||||
<NRadioGroup v-model:value={radioRef.manual}>
|
||||
<NRadioButton value={false}>自动更新</NRadioButton>
|
||||
<NRadioButton value={true}>取消自动</NRadioButton>
|
||||
</NRadioGroup>
|
||||
</NFormItem>
|
||||
</NFlex>
|
||||
</NCard>
|
||||
<NCard title="useTablePro 部分方法">
|
||||
<NFlex>
|
||||
<NButton type="primary" onClick={print}>
|
||||
打印
|
||||
</NButton>
|
||||
<NButton type="primary" onClick={() => downloadCsv()}>
|
||||
下载 csv
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</NCard>
|
||||
<NCard title="useCheckedRowKeys 部分方法">
|
||||
<NFlex>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
const key = tableDataRef[1].key
|
||||
|
||||
selectKey(key)
|
||||
}}
|
||||
>
|
||||
选中第二行
|
||||
</NButton>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
const key = tableDataRef[1].key
|
||||
|
||||
clearKey(key)
|
||||
}}
|
||||
>
|
||||
取消选中第二行
|
||||
</NButton>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
tableDataRef?.forEach((curr) => selectKey(curr.key))
|
||||
}}
|
||||
>
|
||||
选中当前页面所有行
|
||||
</NButton>
|
||||
<NButton
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
clearAll()
|
||||
}}
|
||||
>
|
||||
取消所有已选中行
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</NCard>
|
||||
<RTablePro
|
||||
onRegister={tableProRegister}
|
||||
data={tableDataRef}
|
||||
columns={baseColumns}
|
||||
loading={loadingGetPersonList}
|
||||
// 如果需要设置分页功能,则该参数必传
|
||||
paginationCount={itemCountRef}
|
||||
request={runGetPersonList}
|
||||
requestConfig={{
|
||||
params: conditionRef,
|
||||
// 这是后台的统计字段,根据实际情况配置
|
||||
formatRangeTime: [
|
||||
{
|
||||
key: 'RangeTime',
|
||||
target: ['signTimeStart', 'signTimeEnd'],
|
||||
},
|
||||
],
|
||||
}}
|
||||
showPagination={radioRef.pagination}
|
||||
manual={radioRef.manual}
|
||||
rowKey={(row) => row.key}
|
||||
v-model:checkedRowKeys={this.checkedRowKeys}
|
||||
onUpdateCheckedRowKeys={checkedRowKeysBind}
|
||||
/>
|
||||
</NFlex>
|
||||
)
|
||||
},
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user