Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
najiu-admin-template
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
najiu-frontend
najiu-admin-template
Commits
faf3f460
Commit
faf3f460
authored
Oct 08, 2020
by
陈文彬
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(table): add table component
parent
5b0a21ec
Changes
71
Hide whitespace changes
Inline
Side-by-side
Showing
71 changed files
with
3937 additions
and
191 deletions
+3937
-191
release-drafter.yml
.github/release-drafter.yml
+1
-1
README.md
README.md
+8
-18
_createProductionServer.ts
mock/_createProductionServer.ts
+2
-1
_util.ts
mock/_util.ts
+10
-3
table-demo.ts
mock/demo/table-demo.ts
+30
-0
App.vue
src/App.vue
+2
-8
tableModel.ts
src/api/demo/model/tableModel.ts
+20
-0
table.ts
src/api/demo/table.ts
+17
-0
baseModel.ts
src/api/model/baseModel.ts
+9
-0
lock-page.png
src/assets/images/lock-page.png
+0
-0
page_null.png
src/assets/images/page_null.png
+0
-0
index.ts
src/components/Basic/index.ts
+0
-1
BasicArrow.vue
src/components/Basic/src/BasicArrow.vue
+7
-2
BasicEmpty.vue
src/components/Basic/src/BasicEmpty.vue
+0
-28
index.vue
src/components/Button/index.vue
+2
-2
CollapseContainer.vue
src/components/Container/src/collapse/CollapseContainer.vue
+1
-1
BasicForm.vue
src/components/Form/src/BasicForm.vue
+2
-2
index.ts
src/components/Table/index.ts
+13
-0
BasicTable.vue
src/components/Table/src/BasicTable.vue
+285
-0
componentMap.ts
src/components/Table/src/componentMap.ts
+26
-0
CellResize.tsx
src/components/Table/src/components/CellResize.tsx
+72
-0
EditTableHeaderIcon.vue
src/components/Table/src/components/EditTableHeaderIcon.vue
+21
-0
TableAction.tsx
src/components/Table/src/components/TableAction.tsx
+144
-0
TableImg.vue
src/components/Table/src/components/TableImg.vue
+36
-0
TableTitle.vue
src/components/Table/src/components/TableTitle.vue
+41
-0
renderEditableCell.tsx
src/components/Table/src/components/renderEditableCell.tsx
+153
-0
renderExpandIcon.tsx
src/components/Table/src/components/renderExpandIcon.tsx
+15
-0
renderFooter.tsx
src/components/Table/src/components/renderFooter.tsx
+64
-0
renderTitle.tsx
src/components/Table/src/components/renderTitle.tsx
+14
-0
const.ts
src/components/Table/src/const.ts
+12
-0
useColumns.ts
src/components/Table/src/hooks/useColumns.ts
+123
-0
useDataSource.ts
src/components/Table/src/hooks/useDataSource.ts
+148
-0
useLoading.ts
src/components/Table/src/hooks/useLoading.ts
+15
-0
usePagination.tsx
src/components/Table/src/hooks/usePagination.tsx
+53
-0
useProps.ts
src/components/Table/src/hooks/useProps.ts
+29
-0
useProvinceTable.ts
src/components/Table/src/hooks/useProvinceTable.ts
+12
-0
useRowSelection.ts
src/components/Table/src/hooks/useRowSelection.ts
+63
-0
useTable.ts
src/components/Table/src/hooks/useTable.ts
+88
-0
useTableScroll.ts
src/components/Table/src/hooks/useTableScroll.ts
+134
-0
props.ts
src/components/Table/src/props.ts
+155
-0
editable-cell.less
src/components/Table/src/style/editable-cell.less
+41
-0
index.less
src/components/Table/src/style/index.less
+228
-0
componentType.ts
src/components/Table/src/types/componentType.ts
+8
-0
pagination.ts
src/components/Table/src/types/pagination.ts
+89
-0
table.ts
src/components/Table/src/types/table.ts
+315
-0
tableAction.ts
src/components/Table/src/types/tableAction.ts
+19
-0
pagination.less
src/design/ant/pagination.less
+75
-77
LayoutContent.tsx
src/layouts/default/LayoutContent.tsx
+7
-1
index.tsx
src/layouts/page/index.tsx
+25
-31
progressGuard.ts
src/router/guard/progressGuard.ts
+3
-3
comp.ts
src/router/menus/modules/demo/comp.ts
+62
-0
comp.ts
src/router/routes/modules/demo/comp.ts
+122
-0
index.ts
src/store/index.ts
+6
-3
source.d.ts
src/types/source.d.ts
+1
-0
useApp.tsx
src/useApp.tsx
+0
-7
index.vue
src/views/demo/comp/verify/index.vue
+2
-2
Basic.vue
src/views/demo/table/Basic.vue
+70
-0
CustomerCell.vue
src/views/demo/table/CustomerCell.vue
+70
-0
EditCellTable.vue
src/views/demo/table/EditCellTable.vue
+60
-0
ExpandTable.vue
src/views/demo/table/ExpandTable.vue
+34
-0
FetchTable.vue
src/views/demo/table/FetchTable.vue
+44
-0
FixedColumn.vue
src/views/demo/table/FixedColumn.vue
+93
-0
FixedHeight.vue
src/views/demo/table/FixedHeight.vue
+40
-0
FooterTable.vue
src/views/demo/table/FooterTable.vue
+50
-0
FormTable.vue
src/views/demo/table/FormTable.vue
+27
-0
MergeHeader.vue
src/views/demo/table/MergeHeader.vue
+27
-0
MultipleHeader.vue
src/views/demo/table/MultipleHeader.vue
+26
-0
RefTable.vue
src/views/demo/table/RefTable.vue
+119
-0
TreeTable.vue
src/views/demo/table/TreeTable.vue
+29
-0
UseTable.vue
src/views/demo/table/UseTable.vue
+126
-0
tableData.tsx
src/views/demo/table/tableData.tsx
+292
-0
No files found.
.github/release-drafter.yml
View file @
faf3f460
...
...
@@ -30,5 +30,5 @@ categories:
-
'
workflow'
change-template
:
'
-
$TITLE
(#$NUMBER)
@$AUTHOR'
template
:
|
#
Changes
#
What's Changed
$CHANGES
README.md
View file @
faf3f460
...
...
@@ -7,20 +7,18 @@
**中文**
该分支为
2.0新分支,使用vue3
进行开发。
该分支为
2.0 新分支,使用 vue3
进行开发。
1.
0
分支请切换到
`master`
分支。1.0
采用
`vue2.6`
+
`vue-composition-api`
+
`vue-cli`
开发
1.
0
分支请切换到
`master`
分支。1.0
采用
`vue2.6`
+
`vue-composition-api`
+
`vue-cli`
开发
一个适合开发中大型项目的基础框架,需要对
`vue`
,
`typescript`
有一定的了解,也可以作为了解新写法的一个例子来看,提前适应后续新版本的开发方式
项目基于
`ant-design-vue`
,
`typescript`
,
`vue3.0`
,
`vite`
,
`tailwindcss`
,
`tsx`
实现的 vue3 风格的后台管理系统,
### gitHub 地址
[
vue-vben-admin2.0
](
https://github.com/anncwb/vue-vben-admin
)
<p
align=
"center"
>
<img
alt=
"VbenAdmin Logo"
width=
"100%"
src=
"./build/docs/imgs/preview1.png"
>
<img
alt=
"VbenAdmin Logo"
width=
"100%"
src=
"./build/docs/imgs/preview2.png"
>
...
...
@@ -29,11 +27,7 @@
### 文档
2.
0文档还没开始写。后续补上。。
2.
0 文档还没开始写。后续补上。。
## 使用到的技术
...
...
@@ -84,7 +78,6 @@ VSCode 插件
-
`stylelint`
: 样式代码检查
-
`Prettier - Code formatter`
:代码格式化
## 安装
```
js
...
...
@@ -122,7 +115,6 @@ yarn build:no-cache # 打包 不会使用hardSource进行打包
yarn report
# 生成构建包表表预览
```
### 格式化
```
bash
...
...
@@ -159,7 +151,6 @@ yarn log # 生成CHANGELOG
-
`mod`
不确定分类的修改
-
`wip`
删除文件
## 代码贡献
1.
Fork 代码!
...
...
@@ -205,20 +196,19 @@ yarn log # 生成CHANGELOG
-
[
x
]
树组件
-
[
x
]
系统性能优化
-
[
x
]
兼容最新
`vuex`
,
`vue-router`
-
[]
图片预览组件
-
[
x
]
图片预览组件
-
[
]
表格组件
-
[
]
可编辑表格
-
[
]
图表库
-
[
]
数字动画
-
[
]
主题配置
-
[
]
表格组件
-
[
]
富文本组件
-
[
]
首屏加载等待动画
-
[
]
上传组件
-
[
]
可编辑表格
-
[
]
数据导入导出
-
[
]
搭建
`vite`
版本
-
[
]
懒加载组件
-
[
]
黑暗主题
-
[
]
更多组件/功能/建议/bug/欢迎提交 pr 或者 issue
更多组件/功能/建议/bug/欢迎提交 pr 或者 issue
## 加入我们
...
...
mock/_createProductionServer.ts
View file @
faf3f460
import
{
createProdMockServer
}
from
'
vite-plugin-mock/es/createProdMockServer
'
;
import
userMock
from
'
./sys/user
'
;
import
menuMock
from
'
./sys/menu
'
;
import
tableDemoMock
from
'
./demo/table-demo
'
;
export
function
setupProdMockServer
()
{
createProdMockServer
([...
userMock
,
...
menuMock
]);
createProdMockServer
([...
userMock
,
...
menuMock
,
...
tableDemoMock
]);
}
mock/_util.ts
View file @
faf3f460
...
...
@@ -9,12 +9,19 @@ export function resultSuccess<T = any>(result: T, { message = 'ok' } = {}) {
};
}
export
function
resultPageSuccess
<
T
=
any
>
(
items
:
T
[],
total
:
number
,
{
message
=
'
ok
'
}
=
{})
{
export
function
resultPageSuccess
<
T
=
any
>
(
page
:
number
,
pageSize
:
number
,
list
:
T
[],
{
message
=
'
ok
'
}
=
{}
)
{
const
pageData
=
pagination
(
page
,
pageSize
,
list
);
return
{
code
:
0
,
result
:
{
items
,
total
,
items
:
pageData
,
total
:
list
.
length
,
},
message
,
type
:
'
success
'
,
...
...
mock/demo/table-demo.ts
0 → 100644
View file @
faf3f460
import
{
MockMethod
}
from
'
vite-plugin-mock
'
;
import
{
resultPageSuccess
}
from
'
../_util
'
;
const
demoList
=
(()
=>
{
const
result
:
any
[]
=
[];
for
(
let
index
=
0
;
index
<
60
;
index
++
)
{
result
.
push
({
id
:
`
${
index
}
`
,
beginTime
:
'
@datetime
'
,
endTime
:
'
@datetime
'
,
address
:
'
@city()
'
,
name
:
'
@cname()
'
,
'
no|100000-10000000
'
:
100000
,
'
status|1
'
:
[
'
正常
'
,
'
启用
'
,
'
停用
'
],
});
}
return
result
;
})();
export
default
[
{
url
:
'
/api/table/getDemoList
'
,
timeout
:
1000
,
method
:
'
get
'
,
response
:
({
query
})
=>
{
const
{
page
=
1
,
pageSize
=
20
}
=
query
;
return
resultPageSuccess
(
page
,
pageSize
,
demoList
);
},
},
]
as
MockMethod
[];
src/App.vue
View file @
faf3f460
<
template
>
<ConfigProvider
:locale=
"zhCN"
:renderEmpty=
"renderEmpty"
:transformCellText=
"transformCellText"
v-bind=
"lockOn"
>
<ConfigProvider
:locale=
"zhCN"
:transformCellText=
"transformCellText"
v-bind=
"lockOn"
>
<router-view
/>
</ConfigProvider>
</
template
>
...
...
@@ -28,10 +23,9 @@
useInitAppConfigStore
();
useListenerNetWork
();
createBreakpointListen
();
const
{
renderEmpty
,
transformCellText
}
=
useConfigProvider
();
const
{
transformCellText
}
=
useConfigProvider
();
const
{
on
:
lockOn
}
=
useLockPage
();
return
{
renderEmpty
,
transformCellText
,
zhCN
,
lockOn
,
...
...
src/api/demo/model/tableModel.ts
0 → 100644
View file @
faf3f460
import
{
BasicPageParams
,
BasicFetchResult
}
from
'
/@/api/model/baseModel
'
;
/**
* @description: 请求列表接口参数
*/
export
type
DemoParams
=
BasicPageParams
;
export
interface
DemoListItem
{
id
:
string
;
beginTime
:
string
;
endTime
:
string
;
address
:
string
;
name
:
string
;
no
:
number
;
status
:
number
;
}
/**
* @description: 请求列表返回值
*/
export
type
DemoListGetResultModel
=
BasicFetchResult
<
DemoListItem
>
;
src/api/demo/table.ts
0 → 100644
View file @
faf3f460
import
{
defHttp
}
from
'
/@/utils/http/axios
'
;
import
{
DemoParams
,
DemoListGetResultModel
}
from
'
./model/tableModel
'
;
enum
Api
{
DEMO_LIST
=
'
/table/getDemoList
'
,
}
/**
* @description: 获取示例列表值
*/
export
function
demoListApi
(
params
:
DemoParams
)
{
return
defHttp
.
request
<
DemoListGetResultModel
>
({
url
:
Api
.
DEMO_LIST
,
method
:
'
GET
'
,
params
,
});
}
src/api/model/baseModel.ts
0 → 100644
View file @
faf3f460
export
interface
BasicPageParams
{
page
:
number
;
pageSize
:
number
;
}
export
interface
BasicFetchResult
<
T
extends
any
>
{
items
:
T
;
total
:
number
;
}
src/assets/images/lock-page.png
deleted
100644 → 0
View file @
5b0a21ec
372 KB
src/assets/images/page_null.png
deleted
100644 → 0
View file @
5b0a21ec
9.9 KB
src/components/Basic/index.ts
View file @
faf3f460
export
{
default
as
BasicArrow
}
from
'
./src/BasicArrow.vue
'
;
export
{
default
as
BasicHelp
}
from
'
./src/BasicHelp
'
;
export
{
default
as
BasicTitle
}
from
'
./src/BasicTitle.vue
'
;
export
{
default
as
BasicEmpty
}
from
'
./src/BasicEmpty.vue
'
;
src/components/Basic/src/BasicArrow.vue
View file @
faf3f460
...
...
@@ -43,11 +43,16 @@
&.right {
transform: rotate(0deg);
> span {
transition: all 0.3s ease 0.1s !important;
}
}
&__active {
transform: rotate(90deg) !important;
transition: all 0.3s ease 0.1s !important;
> span {
transform: rotate(90deg) !important;
}
}
}
</
style
>
src/components/Basic/src/BasicEmpty.vue
deleted
100644 → 0
View file @
5b0a21ec
<
template
>
<Empty
:image=
"image"
:description=
"description"
/>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
Empty
}
from
'
ant-design-vue
'
;
import
emptySrc
from
'
/@/assets/images/page_null.png
'
;
export
default
defineComponent
({
extends
:
Empty
as
any
,
components
:
{
Empty
},
props
:
{
description
:
{
type
:
String
,
default
:
'
暂无内容
'
,
},
image
:
{
type
:
String
,
default
:
emptySrc
,
required
:
false
,
},
},
setup
()
{
return
{};
},
});
</
script
>
src/components/Button/index.vue
View file @
faf3f460
<
template
>
<Button
v-bind=
"getBindValue"
:class=
"[getColor, $attrs.class]"
>
<template
v-slot:
[
item
]
v-for=
"item in Object.keys($slots)"
>
<slot
:name=
"item"
/>
<template
#[item]=
"data"
v-for=
"item in Object.keys($slots)"
>
<slot
:name=
"item"
v-bind=
"data"
/>
</
template
>
</Button>
</template>
...
...
src/components/Container/src/collapse/CollapseContainer.vue
View file @
faf3f460
...
...
@@ -6,7 +6,7 @@
<div
class=
"collapse-container__body"
v-else
v-show=
"show"
>
<LazyContainer
:timeout=
"lazyTime"
v-if=
"lazy"
>
<slot
/>
<template
v-slot:
skeleton
>
<template
#
skeleton
>
<slot
name=
"lazySkeleton"
/>
</
template
>
</LazyContainer>
...
...
src/components/Form/src/BasicForm.vue
View file @
faf3f460
...
...
@@ -9,8 +9,8 @@
:allDefaultValues=
"getAllDefaultValues"
:formModel=
"formModel"
>
<template
v-slot:
[
item
]
v-for=
"item in Object.keys($slots)"
>
<slot
:name=
"item"
/>
<template
#[item]=
"data"
v-for=
"item in Object.keys($slots)"
>
<slot
:name=
"item"
v-bind=
"data"
/>
</
template
>
</FormItem>
</template>
...
...
src/components/Table/index.ts
0 → 100644
View file @
faf3f460
export
{
default
as
BasicTable
}
from
'
./src/BasicTable.vue
'
;
export
{
default
as
TableAction
}
from
'
./src/components/TableAction
'
;
export
{
default
as
TableImg
}
from
'
./src/components/TableImg.vue
'
;
export
{
renderEditableCell
}
from
'
./src/components/renderEditableCell
'
;
export
{
default
as
EditTableHeaderIcon
}
from
'
./src/components/EditTableHeaderIcon.vue
'
;
export
*
from
'
./src/types/table
'
;
export
*
from
'
./src/types/pagination
'
;
export
*
from
'
./src/types/tableAction
'
;
export
{
useTable
}
from
'
./src/hooks/useTable
'
;
export
type
{
FormSchema
,
FormProps
}
from
'
/@/components/Form/src/types/form
'
;
src/components/Table/src/BasicTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"basic-table"
:class=
"
{
'table-form-container': getBindValues.useSearchForm,
}"
>
<BasicForm
v-bind=
"getFormProps"
v-if=
"getBindValues.useSearchForm"
:submitButtonOptions=
"
{ loading }"
@register="registerForm"
@submit="handleSearchInfoChange"
@advanced-change="redoHeight"
>
<template
#[item]=
"data"
v-for=
"item in Object.keys($slots)"
>
<slot
:name=
"`form-$
{item}`" v-bind="data" />
</
template
>
</BasicForm>
<Table
ref=
"tableElRef"
v-bind=
"getBindValues"
:rowClassName=
"getRowClassName"
:class=
"{
hidden: !getEmptyDataIsShowTable,
}"
@
change=
"handleTableChange"
>
<
template
#[item]=
"data"
v-for=
"item in Object.keys($slots)"
>
<slot
:name=
"item"
v-bind=
"data"
/>
</
template
>
</Table>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
ref
,
computed
,
unref
,
watch
,
nextTick
}
from
'
vue
'
;
import
{
Table
}
from
'
ant-design-vue
'
;
import
{
basicProps
}
from
'
./props
'
;
import
type
{
BasicTableProps
,
FetchParams
,
GetColumnsParams
,
TableActionType
,
}
from
'
./types/table
'
;
import
{
isFunction
,
isString
}
from
'
/@/utils/is
'
;
import
renderTitle
from
'
./components/renderTitle
'
;
import
renderFooter
from
'
./components/renderFooter
'
;
import
renderExpandIcon
from
'
./components/renderExpandIcon
'
;
import
{
usePagination
}
from
'
./hooks/usePagination
'
;
import
{
useColumns
}
from
'
./hooks/useColumns
'
;
import
{
useDataSource
}
from
'
./hooks/useDataSource
'
;
import
{
useLoading
}
from
'
./hooks/useLoading
'
;
import
{
useRowSelection
}
from
'
./hooks/useRowSelection
'
;
import
{
useTableScroll
}
from
'
./hooks/useTableScroll
'
;
import
{
provideTable
}
from
'
./hooks/useProvinceTable
'
;
import
{
BasicForm
,
FormProps
,
useForm
}
from
'
/@/components/Form/index
'
;
import
{
omit
}
from
'
lodash-es
'
;
import
'
./style/index.less
'
;
import
{
ROW_KEY
}
from
'
./const
'
;
import
{
PaginationProps
}
from
'
./types/pagination
'
;
import
{
deepMerge
}
from
'
/@/utils
'
;
import
{
TableCustomRecord
}
from
'
ant-design-vue/types/table/table
'
;
import
{
useEvent
}
from
'
/@/hooks/event/useEvent
'
;
export
default
defineComponent
({
props
:
basicProps
,
components
:
{
Table
,
BasicForm
},
emits
:
[
'
fetch-success
'
,
'
fetch-error
'
,
'
selection-change
'
,
'
register
'
],
setup
(
props
,
{
attrs
,
emit
,
slots
})
{
const
tableElRef
=
ref
<
any
>
(
null
);
const
innerPropsRef
=
ref
<
Partial
<
BasicTableProps
>>
();
const
[
registerForm
,
{
getFieldsValue
}]
=
useForm
();
const
getMergeProps
=
computed
(
():
BasicTableProps
=>
{
return
{
...
props
,
...
unref
(
innerPropsRef
),
}
as
BasicTableProps
;
}
);
const
{
loadingRef
}
=
useLoading
(
getMergeProps
);
const
{
getPaginationRef
,
setPagination
}
=
usePagination
(
getMergeProps
);
const
{
getColumnsRef
,
setColumns
}
=
useColumns
(
getMergeProps
,
getPaginationRef
);
const
{
getDataSourceRef
,
setTableData
,
fetch
,
getAutoCreateKey
}
=
useDataSource
(
getMergeProps
,
{
getPaginationRef
,
loadingRef
,
setPagination
,
getFieldsValue
,
},
emit
);
const
{
getScrollRef
,
redoHeight
}
=
useTableScroll
(
getMergeProps
,
tableElRef
);
const
{
getRowSelectionRef
,
getSelectRows
,
clearSelectedRowKeys
,
getSelectRowKeys
,
deleteSelectRowByKey
,
setSelectedRowKeys
,
}
=
useRowSelection
(
getMergeProps
,
emit
);
const
getRowKey
=
computed
(()
=>
{
const
{
rowKey
}
=
unref
(
getMergeProps
);
return
unref
(
getAutoCreateKey
)
?
ROW_KEY
:
rowKey
;
});
const
getBindValues
=
computed
(()
=>
{
const
{
title
,
titleHelpMessage
,
showSummary
}
=
unref
(
getMergeProps
);
const
titleData
:
any
=
!
slots
.
tableTitle
&&
!
isString
(
title
)
&&
!
title
&&
!
slots
.
toolbar
?
{}
:
{
title
:
!
slots
.
tableTitle
&&
!
title
&&
!
slots
.
toolbar
?
null
:
renderTitle
.
bind
(
null
,
title
,
titleHelpMessage
,
slots
),
};
const
pagination
=
unref
(
getPaginationRef
);
const
rowSelection
=
unref
(
getRowSelectionRef
);
const
scroll
=
unref
(
getScrollRef
);
const
loading
=
unref
(
loadingRef
);
const
rowKey
=
unref
(
getRowKey
);
const
columns
=
unref
(
getColumnsRef
);
const
dataSource
=
unref
(
getDataSourceRef
);
let
propsData
=
{
size
:
'
middle
'
,
...(
slots
.
expandedRowRender
?
{
expandIcon
:
renderExpandIcon
()
}
:
{}),
...
attrs
,
...
unref
(
getMergeProps
),
...
titleData
,
scroll
,
loading
,
tableLayout
:
'
fixed
'
,
rowSelection
,
rowKey
,
columns
,
pagination
,
dataSource
,
};
if
(
slots
.
expandedRowRender
)
{
propsData
=
omit
(
propsData
,
'
scroll
'
);
}
if
(
showSummary
)
{
propsData
.
footer
=
renderFooter
.
bind
(
null
,
{
scroll
,
columnsRef
:
getColumnsRef
,
summaryFunc
:
unref
(
getMergeProps
).
summaryFunc
,
dataSourceRef
:
getDataSourceRef
,
rowSelectionRef
:
getRowSelectionRef
,
});
}
return
propsData
;
});
const
getFormProps
=
computed
(()
=>
{
const
{
formConfig
}
=
unref
(
getBindValues
);
const
formProps
:
FormProps
=
{
showAdvancedButton
:
true
,
...(
formConfig
as
FormProps
),
compact
:
true
,
};
return
formProps
;
});
const
getEmptyDataIsShowTable
=
computed
(()
=>
{
const
{
emptyDataIsShowTable
,
useSearchForm
}
=
unref
(
getMergeProps
);
if
(
emptyDataIsShowTable
||
!
useSearchForm
)
{
return
true
;
}
return
!!
unref
(
getDataSourceRef
).
length
;
});
function
getRowClassName
(
record
:
TableCustomRecord
<
any
>
,
index
:
number
)
{
const
{
striped
,
rowClassName
}
=
unref
(
getMergeProps
);
if
(
!
striped
)
return
;
if
(
rowClassName
&&
isFunction
(
rowClassName
))
{
return
rowClassName
(
record
);
}
return
(
index
||
0
)
%
2
===
1
?
'
basic-table-row__striped
'
:
''
;
}
function
handleSearchInfoChange
(
info
:
any
)
{
const
{
handleSearchInfoFn
}
=
unref
(
getMergeProps
);
if
(
handleSearchInfoFn
&&
isFunction
(
handleSearchInfoFn
))
{
info
=
handleSearchInfoFn
(
info
)
||
info
;
}
fetch
({
searchInfo
:
info
,
page
:
1
});
}
function
handleTableChange
(
pagination
:
PaginationProps
)
{
const
{
clearSelectOnPageChange
}
=
unref
(
getMergeProps
);
if
(
clearSelectOnPageChange
)
{
clearSelectedRowKeys
();
}
setPagination
(
pagination
);
fetch
();
}
watch
(
()
=>
unref
(
getDataSourceRef
),
()
=>
{
if
(
unref
(
getMergeProps
).
showSummary
)
{
nextTick
(()
=>
{
const
tableEl
=
unref
(
tableElRef
);
if
(
!
tableEl
)
{
return
;
}
const
bodyDomList
=
tableEl
.
$el
.
querySelectorAll
(
'
.ant-table-body
'
)
as
HTMLDivElement
[];
const
bodyDom
=
bodyDomList
[
0
];
useEvent
({
el
:
bodyDom
,
name
:
'
scroll
'
,
listener
:
()
=>
{
const
footerBodyDom
=
tableEl
.
$el
.
querySelector
(
'
.ant-table-footer .ant-table-body
'
)
as
HTMLDivElement
;
if
(
!
footerBodyDom
||
!
bodyDom
)
return
;
footerBodyDom
.
scrollLeft
=
bodyDom
.
scrollLeft
;
},
wait
:
0
,
options
:
true
,
});
});
}
},
{
immediate
:
true
}
);
const
tableAction
:
TableActionType
=
{
reload
:
async
(
opt
?:
FetchParams
)
=>
{
await
fetch
(
opt
);
},
getSelectRows
,
clearSelectedRowKeys
,
getSelectRowKeys
,
deleteSelectRowByKey
,
setPagination
,
setTableData
,
redoHeight
,
setSelectedRowKeys
,
setColumns
,
getPaginationRef
:
()
=>
{
return
unref
(
getPaginationRef
);
},
getColumns
:
(
opt
?:
GetColumnsParams
)
=>
{
const
{
ignoreIndex
}
=
opt
||
{};
let
columns
=
unref
(
getColumnsRef
);
if
(
ignoreIndex
)
{
columns
=
columns
.
filter
((
item
)
=>
item
.
flag
!==
'
INDEX
'
);
}
return
columns
;
},
getDataSource
:
()
=>
{
return
unref
(
getDataSourceRef
);
},
setLoading
:
(
loading
:
boolean
)
=>
{
loadingRef
.
value
=
loading
;
},
setProps
:
(
props
:
Partial
<
BasicTableProps
>
)
=>
{
innerPropsRef
.
value
=
deepMerge
(
unref
(
innerPropsRef
)
||
{},
props
);
},
};
provideTable
(
tableAction
);
emit
(
'
register
'
,
tableAction
);
return
{
tableElRef
,
getBindValues
,
loading
:
loadingRef
,
registerForm
,
handleSearchInfoChange
,
getFormProps
,
getEmptyDataIsShowTable
,
handleTableChange
,
getRowClassName
,
...
tableAction
,
};
},
});
</
script
>
src/components/Table/src/componentMap.ts
0 → 100644
View file @
faf3f460
import
{
Component
}
from
'
vue
'
;
import
{
Input
,
Select
,
Checkbox
,
InputNumber
,
Switch
}
from
'
ant-design-vue
'
;
import
{
ComponentType
}
from
'
./types/componentType
'
;
const
componentMap
=
new
Map
<
ComponentType
,
Component
>
();
componentMap
.
set
(
'
Input
'
,
Input
);
componentMap
.
set
(
'
InputPassword
'
,
Input
.
Password
);
componentMap
.
set
(
'
InputNumber
'
,
InputNumber
);
componentMap
.
set
(
'
Select
'
,
Select
);
componentMap
.
set
(
'
Switch
'
,
Switch
);
componentMap
.
set
(
'
Checkbox
'
,
Checkbox
);
componentMap
.
set
(
'
CheckboxGroup
'
,
Checkbox
.
Group
);
export
function
add
(
compName
:
ComponentType
,
component
:
Component
)
{
componentMap
.
set
(
compName
,
component
);
}
export
function
del
(
compName
:
ComponentType
)
{
componentMap
.
delete
(
compName
);
}
export
{
componentMap
};
src/components/Table/src/components/CellResize.tsx
0 → 100644
View file @
faf3f460
import
{
defineComponent
,
ref
,
computed
,
unref
}
from
'
vue
'
;
import
{
injectTable
}
from
'
../hooks/useProvinceTable
'
;
import
{
getSlot
}
from
'
/@/utils/helper/tsxHelper
'
;
import
VueDraggableResizable
from
'
vue-draggable-resizable
'
;
export
default
defineComponent
({
name
:
'
DragResize
'
,
setup
(
props
,
{
slots
,
attrs
})
{
const
elRef
=
ref
<
HTMLTableRowElement
|
null
>
(
null
);
const
draggingMapRef
=
ref
<
{
[
key
in
string
]:
number
|
string
}
>
({});
const
tableInstance
=
injectTable
();
const
getColumnsRef
=
computed
(()
=>
{
const
columns
=
tableInstance
.
getColumns
();
columns
.
forEach
((
col
)
=>
{
const
{
key
}
=
col
;
if
(
key
)
{
draggingMapRef
.
value
[
key
]
=
col
.
width
as
number
;
}
});
return
columns
;
});
return
()
=>
{
const
{
key
=
''
,
...
restProps
}
=
{
...
attrs
};
const
col
=
unref
(
getColumnsRef
).
find
((
col
)
=>
{
const
k
=
col
.
dataIndex
||
col
.
key
;
return
k
===
key
;
});
if
(
!
col
||
!
col
.
width
)
{
return
<
th
{
...
restProps
}
>
{
getSlot
(
slots
,
'
default
'
)
}
</
th
>;
}
const
onDrag
=
(
x
:
number
)
=>
{
draggingMapRef
.
value
[
key
]
=
0
;
col
.
width
=
Math
.
max
(
x
,
1
);
};
const
onDragstop
=
()
=>
{
const
el
=
unref
(
elRef
);
if
(
!
el
)
{
return
;
}
draggingMapRef
.
value
[
key
]
=
el
.
getBoundingClientRect
().
width
;
};
return
(
<
th
{
...
restProps
}
class=
"resize-table-th"
ref=
{
elRef
}
style=
{
{
width
:
`${col.width}px`
,
}
}
>
{
getSlot
(
slots
,
'
default
'
)
}
<
VueDraggableResizable
key=
{
col
.
key
}
class=
"table-draggable-handle"
w=
{
10
}
x=
{
draggingMapRef
.
value
[
key
]
||
col
.
width
}
z=
{
1
}
axis=
"x"
draggable=
{
true
}
resizable=
{
false
}
onDragging=
{
onDrag
}
onDragstop=
{
onDragstop
}
/>
</
th
>
);
};
},
});
src/components/Table/src/components/EditTableHeaderIcon.vue
0 → 100644
View file @
faf3f460
<
template
>
<span>
{{
title
}}
<FormOutlined
class=
"ml-2"
/>
</span>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
PropType
}
from
'
vue
'
;
import
{
FormOutlined
}
from
'
@ant-design/icons-vue
'
;
export
default
defineComponent
({
name
:
'
EditTableHeaderIcon
'
,
components
:
{
FormOutlined
},
props
:
{
title
:
{
type
:
String
as
PropType
<
string
>
,
default
:
''
,
},
},
setup
()
{},
});
</
script
>
src/components/Table/src/components/TableAction.tsx
0 → 100644
View file @
faf3f460
import
{
defineComponent
,
PropType
}
from
'
vue
'
;
import
{
Dropdown
,
Menu
,
Popconfirm
}
from
'
ant-design-vue
'
;
import
Icon
from
'
/@/components/Icon/index
'
;
import
{
DownOutlined
}
from
'
@ant-design/icons-vue
'
;
import
{
ActionItem
}
from
'
../types/tableAction
'
;
import
Button
from
'
/@/components/Button/index.vue
'
;
const
prefixCls
=
'
basic-table-action
'
;
export
default
defineComponent
({
name
:
'
TableAction
'
,
props
:
{
actions
:
{
type
:
Array
as
PropType
<
ActionItem
[]
>
,
default
:
null
,
},
dropDownActions
:
{
type
:
Array
as
PropType
<
ActionItem
[]
>
,
default
:
null
,
},
},
setup
(
props
)
{
// 增加按钮的TYPE和COLOR
return
()
=>
{
const
{
dropDownActions
=
[],
actions
}
=
props
;
return
(
<
div
class=
{
prefixCls
}
>
{
actions
&&
actions
.
length
&&
actions
.
map
((
action
,
index
)
=>
{
const
{
disabled
=
false
,
label
,
props
,
icon
,
color
=
''
,
type
=
'
link
'
,
popConfirm
=
null
,
}
=
action
;
const
button
=
(
<
Button
type=
{
type
}
size=
"small"
disabled=
{
disabled
}
color=
{
color
}
{
...
props
}
key=
{
index
}
>
{
()
=>
(
<>
{
label
}
{
icon
&&
<
Icon
icon=
{
icon
}
/>
}
</>
)
}
</
Button
>
);
if
(
popConfirm
!==
null
)
{
const
{
title
,
okText
=
'
确定
'
,
cancelText
=
'
取消
'
,
confirm
=
()
=>
{},
cancel
=
()
=>
{},
icon
=
''
,
}
=
popConfirm
;
return
(
<
Popconfirm
key=
{
`P-${index}`
}
title=
{
title
}
onConfirm=
{
confirm
}
onCancel=
{
cancel
}
okText=
{
okText
}
cancelText=
{
cancelText
}
icon=
{
icon
}
>
{
()
=>
button
}
</
Popconfirm
>
);
}
return
button
;
})
}
{
dropDownActions
&&
dropDownActions
.
length
&&
(
<
Dropdown
>
{
{
default
:
()
=>
(
<
Button
type=
"link"
size=
"small"
>
{
{
default
:
()
=>
(
<>
更多
<
DownOutlined
/>
</>
),
}
}
</
Button
>
),
overlay
:
()
=>
{
return
(
<
Menu
>
{
{
default
:
()
=>
{
return
dropDownActions
.
map
((
action
,
index
)
=>
{
const
{
disabled
=
false
,
label
,
props
,
icon
,
color
=
''
,
type
=
'
link
'
,
}
=
action
;
return
(
<
Menu
.
Item
key=
{
`${index}`
}
disabled=
{
disabled
}
>
{
()
=>
(
<
Button
type=
{
type
}
size=
"small"
{
...
props
}
disabled=
{
disabled
}
color=
{
color
}
>
{
{
default
:
()
=>
(
<>
{
label
}
{
icon
&&
<
Icon
icon=
{
icon
}
/>
}
</>
),
}
}
</
Button
>
)
}
</
Menu
.
Item
>
);
});
},
}
}
</
Menu
>
);
},
}
}
</
Dropdown
>
)
}
</
div
>
);
};
},
});
src/components/Table/src/components/TableImg.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"basic-table-img__preview"
v-if=
"imgList && imgList.length"
>
<template
v-for=
"(img, index) in imgList"
:key=
"img"
>
<img
:width=
"size"
@
click=
"handlePreview(index)"
:src=
"img"
/>
</
template
>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
PropType
}
from
'
vue
'
;
import
{
createImgPreview
}
from
'
/@/components/Preview/index
'
;
export
default
defineComponent
({
name
:
'
TableAction
'
,
props
:
{
imgList
:
{
type
:
Array
as
PropType
<
string
[]
>
,
default
:
null
,
},
size
:
{
type
:
Number
as
PropType
<
number
>
,
default
:
40
,
},
},
setup
(
props
)
{
function
handlePreview
(
index
:
number
)
{
const
{
imgList
}
=
props
;
createImgPreview
({
imageList
:
imgList
as
string
[],
index
:
index
,
});
}
return
{
handlePreview
};
},
});
</
script
>
src/components/Table/src/components/TableTitle.vue
0 → 100644
View file @
faf3f460
<
template
>
<BasicTitle
class=
"basic-table-title"
v-if=
"tableTitle"
:helpMessage=
"helpMessage"
>
{{
tableTitle
}}
</BasicTitle>
</
template
>
<
script
lang=
"ts"
>
import
{
computed
,
defineComponent
,
PropType
}
from
'
vue
'
;
import
{
BasicTitle
}
from
'
/@/components/Basic/index
'
;
import
{
isFunction
}
from
'
/@/utils/is
'
;
export
default
defineComponent
({
name
:
'
TableTitle
'
,
components
:
{
BasicTitle
},
props
:
{
title
:
{
type
:
[
Function
,
String
]
as
PropType
<
string
|
((
data
:
any
)
=>
string
)
>
,
},
getSelectRows
:
{
type
:
Function
as
PropType
<
()
=>
any
[]
>
,
},
helpMessage
:
{
type
:
[
String
,
Array
]
as
PropType
<
string
|
string
[]
>
,
},
},
setup
(
props
)
{
const
tableTitle
=
computed
(()
=>
{
const
{
title
,
getSelectRows
=
()
=>
{}
}
=
props
;
let
tit
=
title
;
if
(
isFunction
(
title
))
{
tit
=
title
({
selectRows
:
getSelectRows
(),
});
}
return
tit
;
});
return
{
tableTitle
};
},
});
</
script
>
src/components/Table/src/components/renderEditableCell.tsx
0 → 100644
View file @
faf3f460
import
{
defineComponent
,
PropType
,
ref
,
unref
,
nextTick
}
from
'
vue
'
;
import
{
injectTable
}
from
'
../hooks/useProvinceTable
'
;
import
ClickOutSide
from
'
/@/components/ClickOutSide/index.vue
'
;
import
{
RenderEditableCellParams
}
from
'
../types/table
'
;
import
{
ComponentType
}
from
'
../types/componentType
'
;
import
{
componentMap
}
from
'
../componentMap
'
;
import
'
../style/editable-cell.less
'
;
import
{
isString
,
isBoolean
}
from
'
/@/utils/is
'
;
import
{
FormOutlined
,
CloseOutlined
,
CheckOutlined
}
from
'
@ant-design/icons-vue
'
;
const
prefixCls
=
'
editable-cell
'
;
const
EditableCell
=
defineComponent
({
name
:
'
EditableCell
'
,
props
:
{
value
:
{
type
:
String
as
PropType
<
string
>
,
default
:
''
,
},
componentProps
:
{
type
:
Object
as
PropType
<
any
>
,
default
:
null
,
},
dataKey
:
{
type
:
String
as
PropType
<
string
>
,
default
:
''
,
},
dataIndex
:
{
type
:
String
as
PropType
<
string
>
,
default
:
''
,
},
component
:
{
type
:
String
as
PropType
<
ComponentType
>
,
default
:
'
Input
'
,
},
},
setup
(
props
,
{
attrs
})
{
const
table
=
injectTable
();
const
elRef
=
ref
<
any
>
(
null
);
const
isEditRef
=
ref
(
false
);
const
currentValueRef
=
ref
<
string
|
boolean
>
(
''
);
function
handleChange
(
e
:
ChangeEvent
|
string
|
boolean
)
{
if
((
e
as
ChangeEvent
).
target
&&
Reflect
.
has
((
e
as
ChangeEvent
).
target
,
'
value
'
))
{
currentValueRef
.
value
=
(
e
as
ChangeEvent
).
target
.
value
;
}
if
(
isString
(
e
)
||
isBoolean
(
e
))
{
currentValueRef
.
value
=
e
;
}
}
function
handleEdit
()
{
isEditRef
.
value
=
true
;
nextTick
(()
=>
{
const
el
=
unref
(
elRef
);
el
&&
el
.
focus
&&
el
.
focus
();
});
}
function
handleCancel
()
{
isEditRef
.
value
=
false
;
}
function
handleSubmit
()
{
const
{
dataKey
,
dataIndex
}
=
props
;
if
(
!
dataKey
||
!
dataIndex
)
{
return
;
}
isEditRef
.
value
=
false
;
const
{
getDataSource
}
=
table
;
const
dataSource
=
getDataSource
();
const
target
=
dataSource
.
find
((
item
)
=>
item
.
key
===
dataKey
);
if
(
target
)
{
target
[
dataIndex
]
=
unref
(
currentValueRef
);
}
}
function
onClickOutside
()
{
const
{
component
}
=
props
;
if
(
component
?.
includes
(
'
Input
'
))
{
handleCancel
();
}
}
return
()
=>
{
const
{
value
,
component
,
componentProps
=
{}
}
=
props
;
const
Comp
=
componentMap
.
get
(
component
!
)
as
any
;
// const propsData: any = {};
return
(
<
div
class=
{
prefixCls
}
>
{
unref
(
isEditRef
)
&&
(
<
ClickOutSide
onClickOutside=
{
onClickOutside
}
>
{
()
=>
(
<
div
class=
{
`${prefixCls}__wrapper`
}
>
<
Comp
{
...
{
...
attrs
,
...
componentProps
,
}}
style=
{
{
width
:
'
calc(100% - 48px)
'
}
}
ref=
{
elRef
}
value=
{
value
}
size=
"small"
onChange=
{
handleChange
}
onPressEnter=
{
handleSubmit
}
/>
<
div
class=
{
`${prefixCls}__action`
}
>
<
CheckOutlined
class=
{
[
`${prefixCls}__icon`
,
'
mx-2
'
]
}
onClick=
{
handleSubmit
}
/>
<
CloseOutlined
class=
{
[
`${prefixCls}__icon `
]
}
onClick=
{
handleCancel
}
/>
</
div
>
</
div
>
)
}
</
ClickOutSide
>
)
}
{
!
unref
(
isEditRef
)
&&
(
<
div
class=
{
`${prefixCls}__normal`
}
onClick=
{
handleEdit
}
>
{
value
}
<
FormOutlined
class=
{
`${prefixCls}__normal-icon`
}
/>
</
div
>
)
}
</
div
>
);
};
},
});
export
function
renderEditableCell
({
dataIndex
,
component
,
componentOn
=
{},
componentProps
=
{},
}:
RenderEditableCellParams
)
{
return
({
text
,
record
}:
{
text
:
string
;
record
:
any
})
=>
{
return
(
<
EditableCell
value=
{
text
}
dataKey=
{
record
.
key
}
dataIndex=
{
dataIndex
}
component=
{
component
}
on=
{
componentOn
}
componentProps=
{
componentProps
}
/>
);
};
}
src/components/Table/src/components/renderExpandIcon.tsx
0 → 100644
View file @
faf3f460
import
{
BasicArrow
}
from
'
/@/components/Basic
'
;
export
default
()
=>
{
return
(
props
:
any
)
=>
{
return
(
<
BasicArrow
onClick=
{
(
e
:
Event
)
=>
{
props
.
onExpand
(
props
.
record
,
e
);
}
}
expand=
{
props
.
expanded
}
class=
"right"
/>
);
};
};
src/components/Table/src/components/renderFooter.tsx
0 → 100644
View file @
faf3f460
import
{
Table
}
from
'
ant-design-vue
'
;
import
{
TableRowSelection
}
from
'
ant-design-vue/types/table/table
'
;
import
{
cloneDeep
}
from
'
lodash-es
'
;
import
{
unref
,
ComputedRef
}
from
'
vue
'
;
import
{
BasicColumn
}
from
'
../types/table
'
;
import
{
isFunction
}
from
'
/@/utils/is
'
;
export
default
({
scroll
=
{},
columnsRef
,
summaryFunc
,
rowKey
=
'
key
'
,
dataSourceRef
,
rowSelectionRef
,
}:
{
scroll
:
{
x
?:
number
|
true
;
y
?:
number
};
columnsRef
:
ComputedRef
<
BasicColumn
[]
>
;
summaryFunc
:
any
;
rowKey
?:
string
;
dataSourceRef
:
ComputedRef
<
any
[]
>
;
rowSelectionRef
:
ComputedRef
<
TableRowSelection
<
any
>
|
null
>
;
})
=>
{
if
(
!
summaryFunc
)
{
return
;
}
const
dataSource
:
any
[]
=
isFunction
(
summaryFunc
)
?
summaryFunc
(
unref
(
dataSourceRef
))
:
[];
const
columns
:
BasicColumn
[]
=
cloneDeep
(
unref
(
columnsRef
));
const
index
=
columns
.
findIndex
((
item
)
=>
item
.
flag
===
'
INDEX
'
);
const
hasRowSummary
=
dataSource
.
some
((
item
)
=>
Reflect
.
has
(
item
,
'
_row
'
));
const
hasIndexSummary
=
dataSource
.
some
((
item
)
=>
Reflect
.
has
(
item
,
'
_index
'
));
if
(
index
!==
-
1
)
{
if
(
hasIndexSummary
)
{
columns
[
index
].
customRender
=
({
record
})
=>
record
.
_index
;
columns
[
index
].
ellipsis
=
false
;
}
else
{
Reflect
.
deleteProperty
(
columns
[
index
],
'
customRender
'
);
}
}
if
(
unref
(
rowSelectionRef
)
&&
hasRowSummary
)
{
columns
.
unshift
({
width
:
60
,
title
:
'
selection
'
,
key
:
'
selectionKey
'
,
align
:
'
center
'
,
customRender
:
({
record
})
=>
record
.
_row
,
});
}
dataSource
.
forEach
((
item
,
i
)
=>
{
item
[
rowKey
]
=
i
;
});
return
(
<
Table
showHeader=
{
false
}
bordered=
{
false
}
pagination=
{
false
}
dataSource=
{
dataSource
}
rowKey=
{
rowKey
}
columns=
{
columns
}
tableLayout=
"fixed"
scroll=
{
scroll
as
any
}
/>
);
};
src/components/Table/src/components/renderTitle.tsx
0 → 100644
View file @
faf3f460
import
{
Slots
}
from
'
vue
'
;
import
TableTitle
from
'
./TableTitle.vue
'
;
import
{
getSlot
}
from
'
/@/utils/helper/tsxHelper
'
;
export
default
(
title
:
any
,
titleHelpMessage
:
string
|
string
[],
slots
:
Slots
)
=>
{
return
(
<>
{
getSlot
(
slots
,
'
tableTitle
'
)
||
(
title
&&
<
TableTitle
helpMessage=
{
titleHelpMessage
}
title=
{
title
}
/>)
||
(
<
span
>
</
span
>
)
}
{
slots
.
toolbar
&&
<
div
class=
"basic-table-toolbar"
>
{
getSlot
(
slots
,
'
toolbar
'
)
}
</
div
>
}
</>
);
};
src/components/Table/src/const.ts
0 → 100644
View file @
faf3f460
export
const
ROW_KEY
=
'
key
'
;
export
const
PAGE_SIZE_OPTIONS
=
[
'
10
'
,
'
50
'
,
'
80
'
,
'
100
'
];
export
const
PAGE_SIZE
=
~~
PAGE_SIZE_OPTIONS
[
0
];
export
const
FETCH_SETTING
=
{
pageField
:
'
page
'
,
sizeField
:
'
pageSize
'
,
listField
:
'
items
'
,
totalField
:
'
total
'
,
};
src/components/Table/src/hooks/useColumns.ts
0 → 100644
View file @
faf3f460
import
{
BasicColumn
,
BasicTableProps
}
from
'
../types/table
'
;
import
{
PaginationProps
}
from
'
../types/pagination
'
;
import
{
unref
,
ComputedRef
,
Ref
,
computed
,
watch
,
ref
}
from
'
vue
'
;
import
{
isBoolean
,
isArray
,
isObject
}
from
'
/@/utils/is
'
;
import
{
PAGE_SIZE
}
from
'
../const
'
;
import
{
useProps
}
from
'
./useProps
'
;
export
function
useColumns
(
refProps
:
ComputedRef
<
BasicTableProps
>
,
getPaginationRef
:
ComputedRef
<
false
|
PaginationProps
>
)
{
const
{
propsRef
}
=
useProps
(
refProps
);
const
columnsRef
=
(
ref
(
unref
(
propsRef
).
columns
)
as
unknown
)
as
Ref
<
BasicColumn
[]
>
;
const
cacheColumnsRef
=
(
ref
(
unref
(
propsRef
).
columns
)
as
unknown
)
as
Ref
<
BasicColumn
[]
>
;
watch
(
()
=>
unref
(
propsRef
).
columns
,
(
columns
)
=>
{
columnsRef
.
value
=
columns
;
cacheColumnsRef
.
value
=
columns
;
},
{
immediate
:
true
,
}
);
const
getColumnsRef
=
computed
(()
=>
{
const
props
=
unref
(
propsRef
);
const
{
showIndexColumn
,
indexColumnProps
,
ellipsis
,
actionColumn
,
isTreeTable
}
=
props
;
const
columns
=
unref
(
columnsRef
);
if
(
!
columns
)
{
return
[];
}
let
pushIndexColumns
=
false
;
columns
.
forEach
((
item
)
=>
{
const
{
key
,
dataIndex
}
=
item
;
item
.
align
=
item
.
align
||
'
center
'
;
if
(
ellipsis
)
{
if
(
!
key
)
{
item
.
key
=
dataIndex
;
}
if
(
!
isBoolean
(
item
.
ellipsis
))
{
Object
.
assign
(
item
,
{
ellipsis
,
});
}
}
const
indIndex
=
columns
.
findIndex
((
column
)
=>
column
.
flag
===
'
INDEX
'
);
if
(
showIndexColumn
&&
!
isTreeTable
)
{
pushIndexColumns
=
indIndex
===
-
1
;
}
else
if
(
!
showIndexColumn
&&
!
isTreeTable
&&
indIndex
!==
-
1
)
{
columns
.
splice
(
indIndex
,
1
);
}
});
if
(
pushIndexColumns
)
{
const
isFixedLeft
=
columns
.
some
((
item
)
=>
item
.
fixed
===
'
left
'
);
columns
.
unshift
({
flag
:
'
INDEX
'
,
width
:
50
,
title
:
'
序号
'
,
align
:
'
center
'
,
customRender
:
({
index
})
=>
{
const
getPagination
=
unref
(
getPaginationRef
);
if
(
isBoolean
(
getPagination
))
{
return
`
${
index
+
1
}
`
;
}
const
{
current
=
1
,
pageSize
=
PAGE_SIZE
}
=
getPagination
;
const
currentIndex
=
(
current
-
1
)
*
pageSize
+
index
+
1
;
return
currentIndex
;
},
...(
isFixedLeft
?
{
fixed
:
'
left
'
,
}
:
{}),
...
indexColumnProps
,
});
}
if
(
actionColumn
)
{
const
hasIndex
=
columns
.
findIndex
((
column
)
=>
column
.
flag
===
'
ACTION
'
);
if
(
hasIndex
===
-
1
)
{
columns
.
push
({
fixed
:
'
right
'
,
...
actionColumn
,
flag
:
'
ACTION
'
,
});
}
else
{
columns
[
hasIndex
]
=
{
...
columns
[
hasIndex
],
fixed
:
'
right
'
,
...
actionColumn
,
flag
:
'
ACTION
'
,
};
}
}
return
columns
;
});
function
setColumns
(
columns
:
BasicColumn
[]
|
string
[])
{
if
(
!
isArray
(
columns
))
{
return
;
}
if
(
columns
.
length
<=
0
)
{
columnsRef
.
value
=
[];
return
;
}
const
firstColumn
=
columns
[
0
];
if
(
isObject
(
firstColumn
))
{
columnsRef
.
value
=
columns
as
any
;
}
else
{
const
newColumns
=
unref
(
cacheColumnsRef
).
filter
((
item
)
=>
(
columns
as
string
[]).
includes
(
item
.
key
!
||
item
.
dataIndex
!
)
);
columnsRef
.
value
=
newColumns
;
}
}
return
{
getColumnsRef
,
setColumns
};
}
src/components/Table/src/hooks/useDataSource.ts
0 → 100644
View file @
faf3f460
import
{
useTimeout
}
from
'
/@/hooks/core/useTimeout
'
;
import
{
BasicTableProps
,
FetchParams
}
from
'
../types/table
'
;
import
{
PaginationProps
}
from
'
../types/pagination
'
;
import
{
watch
,
ref
,
unref
,
ComputedRef
,
computed
,
onMounted
,
Ref
}
from
'
vue
'
;
import
{
buildUUID
}
from
'
/@/utils/uuid
'
;
import
{
isFunction
,
isBoolean
}
from
'
/@/utils/is
'
;
import
{
FETCH_SETTING
,
ROW_KEY
}
from
'
../const
'
;
import
{
get
}
from
'
lodash-es
'
;
import
{
useProps
}
from
'
./useProps
'
;
interface
ActionType
{
getPaginationRef
:
ComputedRef
<
false
|
PaginationProps
>
;
setPagination
:
(
info
:
Partial
<
PaginationProps
>
)
=>
void
;
loadingRef
:
Ref
<
boolean
|
undefined
>
;
getFieldsValue
:
()
=>
{
[
field
:
string
]:
any
;
};
}
export
function
useDataSource
(
refProps
:
ComputedRef
<
BasicTableProps
>
,
{
getPaginationRef
,
setPagination
,
loadingRef
,
getFieldsValue
}:
ActionType
,
emit
:
EmitType
)
{
const
{
propsRef
}
=
useProps
(
refProps
);
const
dataSourceRef
=
ref
<
any
[]
>
([]);
watch
(
()
=>
unref
(
propsRef
).
dataSource
,
(
data
:
any
[])
=>
{
const
{
api
}
=
unref
(
propsRef
);
!
api
&&
(
dataSourceRef
.
value
=
data
);
},
{
immediate
:
true
}
);
function
setTableKey
(
items
:
any
[])
{
if
(
!
items
||
!
Array
.
isArray
(
items
))
{
return
;
}
items
.
forEach
((
item
)
=>
{
if
(
!
item
[
ROW_KEY
])
{
item
[
ROW_KEY
]
=
buildUUID
();
}
if
(
item
.
children
&&
item
.
children
.
length
)
{
setTableKey
(
item
.
children
);
}
});
}
const
getAutoCreateKey
=
computed
(()
=>
{
return
unref
(
propsRef
).
autoCreateKey
&&
!
unref
(
propsRef
).
rowKey
;
});
const
getDataSourceRef
=
computed
(()
=>
{
const
dataSource
=
unref
(
dataSourceRef
);
if
(
!
dataSource
||
dataSource
.
length
===
0
)
{
return
[];
}
if
(
unref
(
getAutoCreateKey
))
{
const
firstItem
=
dataSource
[
0
];
const
lastItem
=
dataSource
[
dataSource
.
length
-
1
];
if
(
firstItem
&&
lastItem
)
{
if
(
!
firstItem
[
ROW_KEY
]
||
!
lastItem
[
ROW_KEY
])
{
unref
(
dataSourceRef
).
forEach
((
item
)
=>
{
if
(
!
item
[
ROW_KEY
])
{
item
[
ROW_KEY
]
=
buildUUID
();
}
if
(
item
.
children
&&
item
.
children
.
length
)
{
setTableKey
(
item
.
children
);
}
});
}
}
}
return
unref
(
dataSourceRef
);
});
async
function
fetch
(
opt
?:
FetchParams
)
{
const
{
api
,
searchInfo
,
fetchSetting
,
beforeFetch
,
afterFetch
,
useSearchForm
}
=
unref
(
propsRef
);
if
(
!
api
&&
!
isFunction
(
api
))
return
;
try
{
loadingRef
.
value
=
true
;
const
{
pageField
,
sizeField
,
listField
,
totalField
}
=
fetchSetting
||
FETCH_SETTING
;
let
pageParams
:
any
=
{};
if
(
isBoolean
(
getPaginationRef
))
{
pageParams
=
{};
}
else
{
const
{
current
,
pageSize
}
=
unref
(
getPaginationRef
)
as
PaginationProps
;
pageParams
[
pageField
]
=
opt
?.
page
||
current
;
pageParams
[
sizeField
]
=
pageSize
;
}
let
params
:
any
=
{
...
pageParams
,
...(
useSearchForm
?
getFieldsValue
()
:
{}),
...
searchInfo
,
...(
opt
?
opt
.
searchInfo
:
{}),
};
if
(
beforeFetch
&&
isFunction
(
beforeFetch
))
{
params
=
beforeFetch
(
params
)
||
params
;
}
const
res
=
await
api
(
params
);
let
resultItems
:
any
[]
=
get
(
res
,
listField
);
const
resultTotal
:
number
=
get
(
res
,
totalField
);
if
(
afterFetch
&&
isFunction
(
afterFetch
))
{
resultItems
=
afterFetch
(
resultItems
)
||
resultItems
;
}
dataSourceRef
.
value
=
resultItems
;
setPagination
({
total
:
resultTotal
||
0
,
});
if
(
opt
&&
opt
.
page
)
{
setPagination
({
current
:
opt
.
page
||
1
,
});
}
emit
(
'
fetch-success
'
,
{
items
:
unref
(
resultItems
),
total
:
resultTotal
,
});
}
catch
(
error
)
{
emit
(
'
fetch-error
'
,
error
);
dataSourceRef
.
value
=
[];
setPagination
({
total
:
0
,
});
}
finally
{
loadingRef
.
value
=
false
;
}
}
function
setTableData
(
values
:
any
[])
{
dataSourceRef
.
value
=
values
;
}
onMounted
(()
=>
{
// 转异步任务
useTimeout
(()
=>
{
unref
(
propsRef
).
immediate
&&
fetch
();
},
0
);
});
return
{
getDataSourceRef
,
setTableData
,
getAutoCreateKey
,
fetch
:
fetch
};
}
src/components/Table/src/hooks/useLoading.ts
0 → 100644
View file @
faf3f460
import
{
watch
,
ref
,
ComputedRef
,
unref
}
from
'
vue
'
;
import
{
BasicTableProps
}
from
'
../types/table
'
;
import
{
useProps
}
from
'
./useProps
'
;
export
function
useLoading
(
refProps
:
ComputedRef
<
BasicTableProps
>
)
{
const
{
propsRef
}
=
useProps
(
refProps
);
const
loadingRef
=
ref
(
unref
(
propsRef
).
loading
);
watch
(
()
=>
unref
(
propsRef
).
loading
,
(
v
:
boolean
)
=>
{
loadingRef
.
value
=
v
;
}
);
return
{
loadingRef
};
}
src/components/Table/src/hooks/usePagination.tsx
0 → 100644
View file @
faf3f460
import
{
computed
,
unref
,
ref
,
ComputedRef
}
from
'
vue
'
;
import
{
PaginationProps
}
from
'
../types/pagination
'
;
import
{
isBoolean
}
from
'
/@/utils/is
'
;
import
{
LeftOutlined
,
RightOutlined
}
from
'
@ant-design/icons-vue
'
;
import
{
PAGE_SIZE
,
PAGE_SIZE_OPTIONS
}
from
'
../const
'
;
import
{
useProps
}
from
'
./useProps
'
;
import
{
BasicTableProps
}
from
'
../..
'
;
export
function
usePagination
(
refProps
:
ComputedRef
<
BasicTableProps
>
)
{
const
configRef
=
ref
<
PaginationProps
>
({});
const
{
propsRef
}
=
useProps
(
refProps
);
const
getPaginationRef
=
computed
(():
PaginationProps
|
false
=>
{
const
{
pagination
}
=
unref
(
propsRef
);
if
(
isBoolean
(
pagination
)
&&
!
pagination
)
{
return
false
;
}
return
{
current
:
1
,
pageSize
:
PAGE_SIZE
,
size
:
'
small
'
,
defaultPageSize
:
PAGE_SIZE
,
showTotal
:
(
total
)
=>
`共
${
total
}
条数据`
,
showSizeChanger
:
true
,
pageSizeOptions
:
PAGE_SIZE_OPTIONS
,
itemRender
:
({
page
,
type
,
originalElement
})
=>
{
if
(
type
===
'
prev
'
)
{
if
(
page
===
0
)
{
return
null
;
}
return
<
LeftOutlined
/>;
}
else
if
(
type
===
'
next
'
)
{
if
(
page
===
1
)
{
return
null
;
}
return
<
RightOutlined
/>;
}
return
originalElement
;
},
showQuickJumper
:
true
,
...(
isBoolean
(
pagination
)
?
{}
:
pagination
),
...
unref
(
configRef
),
};
});
function
setPagination
(
info
:
Partial
<
PaginationProps
>
)
{
configRef
.
value
=
{
...
unref
(
getPaginationRef
),
...
info
,
};
}
return
{
getPaginationRef
,
setPagination
};
}
src/components/Table/src/hooks/useProps.ts
0 → 100644
View file @
faf3f460
/*
* @description:
* @author: wenbin.chen
* @Date: 2020-05-12 13:20:26
* @LastEditors: vben
* @LastEditTime: 2020-10-07 14:52:34
* @email: 190848757@qq.com
*/
import
{
Ref
,
ref
,
watch
,
unref
}
from
'
vue
'
;
import
{
BasicTableProps
}
from
'
../types/table
'
;
/**
* @description:
* @Date: 2020-05-12 13:20:37
*/
export
function
useProps
(
props
:
Readonly
<
Ref
<
BasicTableProps
>>
)
{
const
propsRef
=
(
ref
<
BasicTableProps
>
(
unref
(
props
))
as
unknown
)
as
Ref
<
BasicTableProps
>
;
watch
(
()
=>
props
.
value
,
(
v
)
=>
{
propsRef
.
value
=
unref
(
v
);
},
{
immediate
:
false
,
}
);
return
{
propsRef
};
}
src/components/Table/src/hooks/useProvinceTable.ts
0 → 100644
View file @
faf3f460
import
{
provide
,
inject
}
from
'
vue
'
;
import
{
TableActionType
}
from
'
../types/table
'
;
const
key
=
Symbol
(
'
table
'
);
export
function
provideTable
(
instance
:
TableActionType
)
{
provide
(
key
,
instance
);
}
export
function
injectTable
():
TableActionType
{
return
inject
(
key
)
as
TableActionType
;
}
src/components/Table/src/hooks/useRowSelection.ts
0 → 100644
View file @
faf3f460
import
{
computed
,
ref
,
unref
,
ComputedRef
}
from
'
vue
'
;
import
{
BasicTableProps
}
from
'
../types/table
'
;
import
{
TableRowSelection
}
from
'
ant-design-vue/types/table/table
'
;
import
{
useProps
}
from
'
./useProps
'
;
/* eslint-disable */
export
function
useRowSelection
(
refProps
:
ComputedRef
<
BasicTableProps
>
,
emit
:
EmitType
)
{
const
{
propsRef
}
=
useProps
(
refProps
);
const
selectedRowKeysRef
=
ref
<
string
[]
>
([]);
const
selectedRowRef
=
ref
<
any
[]
>
([]);
const
getRowSelectionRef
=
computed
(():
TableRowSelection
<
any
>
|
null
=>
{
const
rowSelection
=
unref
(
propsRef
).
rowSelection
;
if
(
!
rowSelection
)
{
return
null
;
}
return
{
selectedRowKeys
:
unref
(
selectedRowKeysRef
),
hideDefaultSelections
:
false
,
onChange
:
(
selectedRowKeys
:
string
[],
selectedRows
:
any
[])
=>
{
selectedRowKeysRef
.
value
=
selectedRowKeys
;
selectedRowRef
.
value
=
selectedRows
;
emit
(
'
selection-change
'
,
{
keys
:
selectedRowKeys
,
rows
:
selectedRows
,
});
},
...
rowSelection
,
};
});
function
setSelectedRowKeys
(
rowKeys
:
string
[])
{
selectedRowKeysRef
.
value
=
rowKeys
;
}
function
clearSelectedRowKeys
()
{
selectedRowRef
.
value
=
[];
selectedRowKeysRef
.
value
=
[];
}
function
deleteSelectRowByKey
(
key
:
string
)
{
const
selectedRowKeys
=
unref
(
selectedRowKeysRef
);
const
index
=
selectedRowKeys
.
findIndex
((
item
)
=>
item
===
key
);
if
(
index
!==
-
1
)
{
unref
(
selectedRowKeysRef
).
splice
(
index
,
1
);
}
}
function
getSelectRowKeys
()
{
return
unref
(
selectedRowKeysRef
);
}
function
getSelectRows
()
{
return
unref
(
selectedRowRef
);
}
return
{
getRowSelectionRef
,
getSelectRows
,
getSelectRowKeys
,
setSelectedRowKeys
,
clearSelectedRowKeys
,
deleteSelectRowByKey
,
};
}
src/components/Table/src/hooks/useTable.ts
0 → 100644
View file @
faf3f460
import
type
{
BasicTableProps
,
TableActionType
,
FetchParams
,
BasicColumn
}
from
'
../types/table
'
;
import
type
{
PaginationProps
}
from
'
../types/pagination
'
;
import
{
ref
,
getCurrentInstance
,
onUnmounted
,
unref
}
from
'
vue
'
;
import
{
isProdMode
}
from
'
/@/utils/env
'
;
export
function
useTable
(
tableProps
?:
Partial
<
BasicTableProps
>
):
[(
instance
:
TableActionType
)
=>
void
,
TableActionType
]
{
if
(
!
getCurrentInstance
())
{
throw
new
Error
(
'
Please put useTable function in the setup function!
'
);
}
const
tableRef
=
ref
<
TableActionType
|
null
>
(
null
);
const
loadedRef
=
ref
<
boolean
|
null
>
(
false
);
function
register
(
instance
:
TableActionType
)
{
onUnmounted
(()
=>
{
tableRef
.
value
=
null
;
loadedRef
.
value
=
null
;
});
if
(
unref
(
loadedRef
)
&&
isProdMode
()
&&
instance
===
unref
(
tableRef
))
{
return
;
}
tableRef
.
value
=
instance
;
tableProps
&&
instance
.
setProps
(
tableProps
);
loadedRef
.
value
=
true
;
}
function
getTableInstance
():
TableActionType
{
const
table
=
unref
(
tableRef
);
if
(
!
table
)
{
throw
new
Error
(
'
table is undefined!
'
);
}
return
table
;
}
const
methods
:
TableActionType
=
{
reload
:
(
opt
?:
FetchParams
)
=>
{
getTableInstance
().
reload
(
opt
);
},
setProps
:
(
props
:
Partial
<
BasicTableProps
>
)
=>
{
getTableInstance
().
setProps
(
props
);
},
redoHeight
:
()
=>
{
getTableInstance
().
redoHeight
();
},
setLoading
:
(
loading
:
boolean
)
=>
{
getTableInstance
().
setLoading
(
loading
);
},
getDataSource
:
()
=>
{
return
getTableInstance
().
getDataSource
();
},
getColumns
:
({
ignoreIndex
=
false
}:
{
ignoreIndex
?:
boolean
}
=
{})
=>
{
const
columns
=
getTableInstance
().
getColumns
({
ignoreIndex
})
||
[];
return
columns
;
},
setColumns
:
(
columns
:
BasicColumn
[])
=>
{
getTableInstance
().
setColumns
(
columns
);
},
setTableData
:
(
values
:
any
[])
=>
{
return
getTableInstance
().
setTableData
(
values
);
},
setPagination
:
(
info
:
Partial
<
PaginationProps
>
)
=>
{
return
getTableInstance
().
setPagination
(
info
);
},
deleteSelectRowByKey
:
(
key
:
string
)
=>
{
getTableInstance
().
deleteSelectRowByKey
(
key
);
},
getSelectRowKeys
:
()
=>
{
return
getTableInstance
().
getSelectRowKeys
();
},
getSelectRows
:
()
=>
{
return
getTableInstance
().
getSelectRows
();
},
clearSelectedRowKeys
:
()
=>
{
getTableInstance
().
clearSelectedRowKeys
();
},
setSelectedRowKeys
:
(
keys
:
string
[]
|
number
[])
=>
{
getTableInstance
().
setSelectedRowKeys
(
keys
);
},
getPaginationRef
:
()
=>
{
return
getTableInstance
().
getPaginationRef
();
},
}
as
TableActionType
;
return
[
register
,
methods
];
}
src/components/Table/src/hooks/useTableScroll.ts
0 → 100644
View file @
faf3f460
import
{
BasicTableProps
}
from
'
../types/table
'
;
import
{
computed
,
Ref
,
onMounted
,
unref
,
ref
,
nextTick
,
ComputedRef
,
watch
}
from
'
vue
'
;
import
{
getViewportOffset
}
from
'
/@/utils/domUtils
'
;
import
{
triggerWindowResize
}
from
'
/@/utils/event/triggerWindowResizeEvent
'
;
import
{
isBoolean
}
from
'
/@/utils/is
'
;
import
{
useTimeout
}
from
'
/@/hooks/core/useTimeout
'
;
import
{
useWindowSizeFn
}
from
'
/@/hooks/event/useWindowSize
'
;
import
{
useProps
}
from
'
./useProps
'
;
export
function
useTableScroll
(
refProps
:
ComputedRef
<
BasicTableProps
>
,
tableElRef
:
Ref
<
any
>
)
{
const
{
propsRef
}
=
useProps
(
refProps
);
const
tableHeightRef
:
Ref
<
number
|
null
>
=
ref
(
null
);
watch
(
()
=>
unref
(
propsRef
).
canResize
,
()
=>
{
redoHeight
();
}
);
function
redoHeight
()
{
const
{
canResize
}
=
unref
(
propsRef
);
if
(
!
canResize
)
{
return
;
}
calcTableHeight
();
}
async
function
calcTableHeight
(
cb
?:
()
=>
void
)
{
const
{
canResize
,
resizeHeightOffset
,
pagination
,
maxHeight
}
=
unref
(
propsRef
);
if
(
!
canResize
)
{
return
;
}
await
nextTick
();
const
table
=
unref
(
tableElRef
)
as
any
;
if
(
!
table
)
{
return
;
}
const
tableEl
:
Element
=
table
.
$el
;
if
(
!
tableEl
)
{
return
;
}
const
el
:
HTMLElement
|
null
=
tableEl
.
querySelector
(
'
.ant-table-thead
'
);
// const layoutMain: Element | null = document.querySelector('.default-layout__main ');
if
(
!
el
)
{
return
;
}
// 表格距离底部高度
const
{
bottomIncludeBody
}
=
getViewportOffset
(
el
);
// 表格高度+距离底部高度-自定义偏移量
const
paddingHeight
=
32
;
const
borderHeight
=
2
*
2
;
// 分页器高度
// TODO 先固定20
const
paginationHeight
=
20
;
// if (!isBoolean(pagination)) {
// const paginationDom = tableEl.querySelector('.ant-pagination') as HTMLElement;
// if (paginationDom) {
// const offsetHeight = paginationDom.offsetHeight;
// paginationHeight += offsetHeight || 0;
// }
// }
let
footerHeight
=
0
;
if
(
!
isBoolean
(
pagination
))
{
const
footerEl
=
tableEl
.
querySelector
(
'
.ant-table-footer
'
)
as
HTMLElement
;
if
(
footerEl
)
{
const
offsetHeight
=
footerEl
.
offsetHeight
;
footerHeight
+=
offsetHeight
||
0
;
}
}
let
headerHeight
=
0
;
if
(
el
)
{
headerHeight
=
(
el
as
HTMLElement
).
offsetHeight
;
}
tableHeightRef
.
value
=
bottomIncludeBody
-
(
resizeHeightOffset
||
0
)
-
paddingHeight
-
borderHeight
-
paginationHeight
-
footerHeight
-
headerHeight
;
useTimeout
(()
=>
{
tableHeightRef
.
value
=
tableHeightRef
.
value
!
>
maxHeight
!
?
(
maxHeight
as
number
)
:
tableHeightRef
.
value
;
cb
&&
cb
();
},
0
);
}
const
getCanResize
=
computed
(()
=>
{
const
{
canResize
,
scroll
}
=
unref
(
propsRef
);
return
canResize
&&
!
(
scroll
||
{}).
y
;
});
useWindowSizeFn
(
calcTableHeight
,
100
);
// function clear() {
// window.clearInterval(timer);
// }
onMounted
(()
=>
{
if
(
unref
(
getCanResize
))
{
calcTableHeight
();
const
hasFixedLeft
=
(
unref
(
propsRef
).
columns
||
[]).
some
((
item
)
=>
item
.
fixed
===
'
left
'
);
// TODO antv table问题情况太多,只能先用下面方式定时器hack
useTimeout
(()
=>
{
calcTableHeight
(()
=>
{
// 有左侧固定列的时候才有问题
hasFixedLeft
&&
useTimeout
(()
=>
{
triggerWindowResize
();
},
300
);
});
},
200
);
}
});
const
getScrollRef
=
computed
(()
=>
{
const
tableHeight
=
unref
(
tableHeightRef
);
const
{
canResize
,
scroll
}
=
unref
(
propsRef
);
return
{
x
:
'
100%
'
,
y
:
canResize
?
tableHeight
:
null
,
scrollToFirstRowOnChange
:
false
,
...
scroll
,
};
});
return
{
getScrollRef
,
redoHeight
};
}
src/components/Table/src/props.ts
0 → 100644
View file @
faf3f460
import
{
PropType
}
from
'
vue
'
;
import
{
PaginationProps
}
from
'
./types/pagination
'
;
import
{
BasicColumn
,
FetchSetting
}
from
'
./types/table
'
;
import
{
TableCustomRecord
,
TableRowSelection
}
from
'
ant-design-vue/types/table/table
'
;
import
{
FormProps
}
from
'
/@/components/Form/index
'
;
import
{
FETCH_SETTING
}
from
'
./const
'
;
// 注释看 types/table
export
const
basicProps
=
{
autoCreateKey
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
striped
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
showSummary
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
summaryFunc
:
{
type
:
[
Function
,
Array
]
as
PropType
<
(...
arg
:
any
[])
=>
any
[]
>
,
default
:
null
,
},
canColDrag
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
isTreeTable
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
api
:
{
type
:
Function
as
PropType
<
(...
arg
:
any
[])
=>
Promise
<
any
>>
,
default
:
null
,
},
beforeFetch
:
{
type
:
Function
as
PropType
<
Fn
>
,
default
:
null
,
},
afterFetch
:
{
type
:
Function
as
PropType
<
Fn
>
,
default
:
null
,
},
handleSearchInfoFn
:
{
type
:
Function
as
PropType
<
Fn
>
,
default
:
null
,
},
fetchSetting
:
{
type
:
Object
as
PropType
<
FetchSetting
>
,
default
:
()
=>
{
return
FETCH_SETTING
;
},
},
// 立即请求接口
immediate
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
},
emptyDataIsShowTable
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
// 额外的请求参数
searchInfo
:
{
type
:
Object
as
PropType
<
any
>
,
default
:
null
,
},
// 使用搜索表单
useSearchForm
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
// 表单配置
formConfig
:
{
type
:
Object
as
PropType
<
Partial
<
FormProps
>>
,
default
:
null
,
},
columns
:
{
type
:
[
Array
]
as
PropType
<
BasicColumn
[]
>
,
default
:
null
,
},
showIndexColumn
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
indexColumnProps
:
{
type
:
Object
as
PropType
<
BasicColumn
>
,
default
:
null
,
},
actionColumn
:
{
type
:
Object
as
PropType
<
BasicColumn
>
,
default
:
null
,
},
ellipsis
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
canResize
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
clearSelectOnPageChange
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
resizeHeightOffset
:
{
type
:
Number
as
PropType
<
number
>
,
default
:
0
,
},
rowSelection
:
{
type
:
Object
as
PropType
<
TableRowSelection
<
any
>
|
null
>
,
default
:
null
,
},
title
:
{
type
:
[
String
,
Function
]
as
PropType
<
string
|
((
data
:
any
)
=>
any
)
>
,
default
:
null
,
},
titleHelpMessage
:
{
type
:
[
String
,
Array
]
as
PropType
<
string
|
string
[]
>
,
},
maxHeight
:
{
type
:
Number
as
PropType
<
number
>
,
},
dataSource
:
{
type
:
Array
as
PropType
<
any
[]
>
,
default
:
null
,
},
rowKey
:
{
type
:
[
String
,
Function
]
as
PropType
<
string
|
((
record
:
any
)
=>
string
)
>
,
default
:
''
,
},
bordered
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
true
,
},
pagination
:
{
type
:
[
Object
,
Boolean
]
as
PropType
<
PaginationProps
|
boolean
>
,
default
:
null
,
},
loading
:
{
type
:
Boolean
as
PropType
<
boolean
>
,
default
:
false
,
},
rowClassName
:
{
type
:
Function
as
PropType
<
(
record
:
TableCustomRecord
<
any
>
,
index
:
number
)
=>
string
>
,
},
scroll
:
{
type
:
Object
as
PropType
<
{
x
:
number
|
true
;
y
:
number
}
>
,
default
:
null
,
},
};
src/components/Table/src/style/editable-cell.less
0 → 100644
View file @
faf3f460
@import (reference) '../../../../design/index.less';
@prefix-cls: ~'editable-cell';
.@{prefix-cls} {
position: relative;
&__wrapper {
display: flex;
align-items: center;
}
&__icon {
&:hover {
transform: scale(1.2);
svg {
color: @primary-color;
}
}
}
&__normal {
padding-right: 48px;
&-icon {
position: absolute;
top: 4px;
right: 0;
display: none;
width: 20px;
cursor: pointer;
}
}
&:hover {
.@{prefix-cls}__normal-icon {
display: inline-block;
}
}
}
src/components/Table/src/style/index.less
0 → 100644
View file @
faf3f460
@import (reference) '../../../../design/index.less';
@border-color: hsla(0, 0%, 80.8%, 0.25);
.basic-table {
&-title {
display: flex;
justify-content: space-between;
align-items: center;
}
&-row__striped {
td {
background: #fafafa;
}
}
&-img__preview {
display: flex;
img {
margin-right: 4px;
}
}
&-action {
display: flex;
}
&-toolbar {
> * {
margin-right: 10px;
}
}
.resize-table-th {
position: relative !important;
.table-draggable-handle {
position: absolute;
right: -5px;
bottom: 0;
left: auto !important;
height: 100% !important;
cursor: col-resize;
transform: none !important;
touch-action: none;
}
}
&-drag-body {
position: relative;
cursor: move;
}
.drag-line td {
border-top: 2px dashed @primary-color;
}
.ant-table-wrapper {
padding: 8px;
background: #fff;
border-radius: 2px;
.ant-table-title {
padding: 0 0 10px 0 !important;
}
.ant-table.ant-table-bordered .ant-table-title {
border: none !important;
}
}
//
.ant-table {
&-title {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 6px;
}
.ant-table-thead > tr > th,
.ant-table-header {
background: #f1f3f4;
}
.ant-table-tbody > tr.ant-table-row-selected td {
background: fade(@primary-color, 8%) !important;
}
}
.ant-table-bordered .ant-table-header > table,
.ant-table-bordered .ant-table-body > table,
.ant-table-bordered .ant-table-fixed-left table,
.ant-table-bordered .ant-table-fixed-right table {
border: 1px solid @border-color;
}
.ant-table-thead {
th {
border: none;
}
}
.ant-table-bordered .ant-table-tbody > tr > td {
border-bottom: 1px solid @border-color;
&:last-child {
border-right: none !important;
}
}
.ant-table.ant-table-bordered .ant-table-footer,
.ant-table.ant-table-bordered .ant-table-title {
border: 1px solid @border-color !important;
}
.ant-table-bordered.ant-table-empty .ant-table-placeholder {
border: 1px solid @border-color !important;
}
.ant-table td {
white-space: nowrap;
}
.ant-table-row-cell-last {
border-right: none !important;
}
.ant-table-bordered .ant-table-thead > tr > th,
.ant-table-bordered .ant-table-tbody > tr > td {
border-right: 1px solid @border-color;
}
.ant-table-thead > tr > th,
.ant-table-tbody > tr > td {
padding: 9px 8px !important;
}
.ant-pagination {
margin: 10px 0 0 0;
}
.ant-table-body {
overflow-x: auto !important;
overflow-y: scroll !important;
}
.ant-table-header {
margin-bottom: 0 !important;
overflow-x: hidden !important;
overflow-y: scroll !important;
}
.ant-table-fixed-right .ant-table-header {
border-left: 1px solid @border-color;
.ant-table-fixed {
border-bottom: none;
}
}
.ant-table-fixed-left {
.ant-table-header {
overflow-y: hidden !important;
}
.ant-table-fixed {
border-bottom: none;
}
}
.ant-radio {
&-inner {
border-color: @text-color-base;
}
}
.ant-checkbox {
&:not(.ant-checkbox-checked) {
.ant-checkbox-inner {
border-color: @text-color-base;
}
}
}
.ant-table-bordered .ant-table-thead > tr:not(:last-child) > th,
.ant-table-tbody > tr > td {
word-break: break-word;
border-color: @border-color;
}
.ant-table-footer {
padding: 0;
.ant-table-wrapper {
padding: 0;
}
table {
border: none !important;
}
.ant-table-body {
overflow-x: hidden !important;
overflow-y: scroll !important;
}
td {
padding: 12px 8px;
}
}
}
.table-form-container {
padding: 16px;
.ant-form {
padding: 12px 12px 4px 12px;
margin-bottom: 12px;
background: #fff;
border-radius: 2px;
}
.ant-table-wrapper {
border-radius: 2px;
}
}
src/components/Table/src/types/componentType.ts
0 → 100644
View file @
faf3f460
export
type
ComponentType
=
|
'
Input
'
|
'
InputPassword
'
|
'
InputNumber
'
|
'
Select
'
|
'
Checkbox
'
|
'
CheckboxGroup
'
|
'
Switch
'
;
src/components/Table/src/types/pagination.ts
0 → 100644
View file @
faf3f460
import
{
VNodeChild
}
from
'
vue
'
;
import
{
PaginationRenderProps
}
from
'
ant-design-vue/types/pagination
'
;
export
interface
PaginationProps
{
/**
* total number of data items
* @default 0
* @type number
*/
total
?:
number
;
/**
* default initial page number
* @default 1
* @type number
*/
defaultCurrent
?:
number
;
/**
* current page number
* @type number
*/
current
?:
number
;
/**
* default number of data items per page
* @default 10
* @type number
*/
defaultPageSize
?:
number
;
/**
* number of data items per page
* @type number
*/
pageSize
?:
number
;
/**
* Whether to hide pager on single page
* @default false
* @type boolean
*/
hideOnSinglePage
?:
boolean
;
/**
* determine whether pageSize can be changed
* @default false
* @type boolean
*/
showSizeChanger
?:
boolean
;
/**
* specify the sizeChanger options
* @default ['10', '20', '30', '40']
* @type string[]
*/
pageSizeOptions
?:
string
[];
/**
* determine whether you can jump to pages directly
* @default false
* @type boolean
*/
showQuickJumper
?:
boolean
|
object
;
/**
* to display the total number and range
* @type Function
*/
showTotal
?:
(
total
:
number
,
range
:
[
number
,
number
])
=>
any
;
/**
* specify the size of Pagination, can be set to small
* @default ''
* @type string
*/
size
?:
string
;
/**
* whether to use simple mode
* @type boolean
*/
simple
?:
boolean
;
/**
* to customize item innerHTML
* @type Function
*/
itemRender
?:
(
props
:
PaginationRenderProps
)
=>
VNodeChild
|
JSX
.
Element
;
}
src/components/Table/src/types/table.ts
0 → 100644
View file @
faf3f460
import
{
VNodeChild
}
from
'
vue
'
;
import
{
PaginationProps
}
from
'
./pagination
'
;
import
{
FormProps
}
from
'
/@/components/Form/index
'
;
import
{
ExpandedRowRenderRecord
,
PaginationConfig
,
SorterResult
,
TableCurrentDataSource
,
TableCustomRecord
,
TableRowSelection
,
}
from
'
ant-design-vue/types/table/table
'
;
import
{
ColumnProps
}
from
'
ant-design-vue/types/table/column
'
;
import
{
ComponentType
}
from
'
./componentType
'
;
export
declare
type
SortOrder
=
'
ascend
'
|
'
descend
'
;
export
interface
ColumnFilterItem
{
text
?:
string
;
value
?:
string
;
children
?:
any
;
}
export
interface
RenderEditableCellParams
{
dataIndex
:
string
;
component
?:
ComponentType
;
componentOn
?:
{
[
key
:
string
]:
Fn
};
componentProps
?:
any
;
}
export
interface
FetchParams
{
searchInfo
?:
any
;
page
?:
number
;
}
export
interface
GetColumnsParams
{
ignoreIndex
?:
boolean
;
}
export
interface
TableActionType
{
reload
:
(
opt
?:
FetchParams
)
=>
Promise
<
void
>
;
getSelectRows
:
()
=>
any
[];
clearSelectedRowKeys
:
()
=>
void
;
getSelectRowKeys
:
()
=>
string
[];
deleteSelectRowByKey
:
(
key
:
string
)
=>
void
;
setPagination
:
(
info
:
Partial
<
PaginationProps
>
)
=>
void
;
setTableData
:
(
values
:
any
[])
=>
void
;
getColumns
:
({
ignoreIndex
}?:
GetColumnsParams
)
=>
BasicColumn
[];
setColumns
:
(
columns
:
BasicColumn
[]
|
string
[])
=>
void
;
getDataSource
:
()
=>
any
[];
setLoading
:
(
loading
:
boolean
)
=>
void
;
setProps
:
(
props
:
Partial
<
BasicTableProps
>
)
=>
void
;
redoHeight
:
()
=>
void
;
setSelectedRowKeys
:
(
rowKeys
:
string
[]
|
number
[])
=>
void
;
getPaginationRef
:
()
=>
PaginationProps
|
boolean
;
}
export
interface
FetchSetting
{
// 请求接口当前页数
pageField
:
string
;
// 每页显示多少条
sizeField
:
string
;
// 请求结果列表字段 支持 a.b.c
listField
:
string
;
// 请求结果总数字段 支持 a.b.c
totalField
:
string
;
}
export
interface
BasicTableProps
<
T
=
any
>
{
// 斑马纹
striped
?:
boolean
;
// 是否自动生成key
autoCreateKey
?:
boolean
;
// 计算合计行的方法
summaryFunc
?:
(...
arg
:
any
)
=>
any
[];
// 是否显示合计行
showSummary
?:
boolean
;
// 是否可拖拽列
canColDrag
?:
boolean
;
// 是否树表
isTreeTable
?:
boolean
;
// 接口请求对象
api
?:
(...
arg
:
any
)
=>
Promise
<
any
>
;
// 请求之前处理参数
beforeFetch
?:
Fn
;
// 自定义处理接口返回参数
afterFetch
?:
Fn
;
// 查询条件请求之前处理
handleSearchInfoFn
?:
Fn
;
// 请求接口配置
fetchSetting
?:
FetchSetting
;
// 立即请求接口
immediate
?:
boolean
;
// 在开起搜索表单的时候,如果没有数据是否显示表格
emptyDataIsShowTable
?:
boolean
;
// 额外的请求参数
searchInfo
?:
any
;
// 使用搜索表单
useSearchForm
?:
boolean
;
// 表单配置
formConfig
?:
FormProps
;
// 列配置
columns
:
BasicColumn
[];
// 是否显示序号列
showIndexColumn
?:
boolean
;
// 序号列配置
indexColumnProps
?:
BasicColumn
;
actionColumn
?:
BasicColumn
;
// 文本超过宽度是否显示。。。
ellipsis
?:
boolean
;
// 是否可以自适应高度
canResize
?:
boolean
;
// 自适应高度偏移, 计算结果-偏移量
resizeHeightOffset
?:
number
;
// 在分页改变的时候清空选项
clearSelectOnPageChange
?:
boolean
;
//
rowKey
?:
string
|
((
record
:
any
)
=>
string
);
// 数据
dataSource
?:
any
[];
// 标题右侧提示
titleHelpMessage
?:
string
|
string
[];
// 表格滚动最大高度
maxHeight
?:
number
;
// 是否显示边框
bordered
?:
boolean
;
// 分页配置
pagination
?:
PaginationProps
|
boolean
;
// loading加载
loading
?:
boolean
;
/**
* The column contains children to display
* @default 'children'
* @type string | string[]
*/
childrenColumnName
?:
string
|
string
[];
/**
* Override default table elements
* @type object
*/
components
?:
object
;
/**
* Expand all rows initially
* @default false
* @type boolean
*/
defaultExpandAllRows
?:
boolean
;
/**
* Initial expanded row keys
* @type string[]
*/
defaultExpandedRowKeys
?:
string
[];
/**
* Current expanded row keys
* @type string[]
*/
expandedRowKeys
?:
string
[];
/**
* Expanded container render for each row
* @type Function
*/
expandedRowRender
?:
(
record
?:
ExpandedRowRenderRecord
<
T
>
)
=>
VNodeChild
|
JSX
.
Element
;
/**
* Customize row expand Icon.
* @type Function | VNodeChild
*/
expandIcon
?:
Function
|
VNodeChild
|
JSX
.
Element
;
/**
* Whether to expand row by clicking anywhere in the whole row
* @default false
* @type boolean
*/
expandRowByClick
?:
boolean
;
/**
* The index of `expandIcon` which column will be inserted when `expandIconAsCell` is false. default 0
*/
expandIconColumnIndex
?:
number
;
/**
* Table footer renderer
* @type Function | VNodeChild
*/
footer
?:
Function
|
VNodeChild
|
JSX
.
Element
;
/**
* Indent size in pixels of tree data
* @default 15
* @type number
*/
indentSize
?:
number
;
/**
* i18n text including filter, sort, empty text, etc
* @default { filterConfirm: 'Ok', filterReset: 'Reset', emptyText: 'No Data' }
* @type object
*/
locale
?:
object
;
/**
* Row's className
* @type Function
*/
rowClassName
?:
(
record
:
TableCustomRecord
<
T
>
)
=>
string
;
/**
* Row selection config
* @type object
*/
rowSelection
?:
TableRowSelection
<
T
>
;
/**
* Set horizontal or vertical scrolling, can also be used to specify the width and height of the scroll area.
* It is recommended to set a number for x, if you want to set it to true,
* you need to add style .ant-table td { white-space: nowrap; }.
* @type object
*/
scroll
?:
{
x
?:
number
|
true
;
y
?:
number
};
/**
* Whether to show table header
* @default true
* @type boolean
*/
showHeader
?:
boolean
;
/**
* Size of table
* @default 'default'
* @type string
*/
size
?:
'
default
'
|
'
middle
'
|
'
small
'
|
'
large
'
;
/**
* Table title renderer
* @type Function | ScopedSlot
*/
title
?:
VNodeChild
|
JSX
.
Element
;
/**
* Set props on per header row
* @type Function
*/
customHeaderRow
?:
(
column
:
ColumnProps
<
T
>
,
index
:
number
)
=>
object
;
/**
* Set props on per row
* @type Function
*/
customRow
?:
(
record
:
T
,
index
:
number
)
=>
object
;
/**
* `table-layout` attribute of table element
* `fixed` when header/columns are fixed, or using `column.ellipsis`
*
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout
* @version 1.5.0
*/
tableLayout
?:
'
auto
'
|
'
fixed
'
|
string
;
/**
* the render container of dropdowns in table
* @param triggerNode
* @version 1.5.0
*/
getPopupContainer
?:
(
triggerNode
?:
HTMLElement
)
=>
HTMLElement
;
/**
* Data can be changed again before rendering.
* The default configuration of general user empty data.
* You can configured globally through [ConfigProvider](https://antdv.com/components/config-provider-cn/)
*
* @version 1.5.4
*/
transformCellText
?:
Function
;
/**
* Callback executed when pagination, filters or sorter is changed
* @param pagination
* @param filters
* @param sorter
* @param currentDataSource
*/
onChange
?:
(
pagination
:
PaginationConfig
,
filters
:
Partial
<
Record
<
keyof
T
,
string
[]
>>
,
sorter
:
SorterResult
<
T
>
,
extra
:
TableCurrentDataSource
<
T
>
)
=>
void
;
/**
* Callback executed when the row expand icon is clicked
*
* @param expanded
* @param record
*/
onExpand
?:
(
expande
:
boolean
,
record
:
T
)
=>
void
;
/**
* Callback executed when the expanded rows change
* @param expandedRows
*/
onExpandedRowsChange
?:
(
expandedRows
:
string
[]
|
number
[])
=>
void
;
}
export
interface
BasicColumn
<
T
=
any
>
extends
ColumnProps
<
T
>
{
children
?:
BasicColumn
[];
//
flag
?:
'
INDEX
'
|
'
DEFAULT
'
|
'
CHECKBOX
'
|
'
RADIO
'
|
'
ACTION
'
;
}
src/components/Table/src/types/tableAction.ts
0 → 100644
View file @
faf3f460
export
interface
ActionItem
{
on
?:
any
;
label
:
string
;
disabled
?:
boolean
;
color
?:
'
success
'
|
'
error
'
|
'
warning
'
;
type
?:
string
;
props
?:
any
;
icon
?:
string
;
popConfirm
?:
PopConfirm
;
}
export
interface
PopConfirm
{
title
:
string
;
okText
?:
string
;
cancelText
?:
string
;
confirm
:
any
;
cancel
?:
any
;
icon
?:
string
;
}
src/design/ant/pagination.less
View file @
faf3f460
body {
.ant-pagination {
&.mini {
.ant-pagination {
&.mini {
height: 20px;
font-size: 13px;
.ant-pagination-prev,
.ant-pagination-next {
width: 20px;
height: 20px;
font-size: 13px;
.ant-pagination-prev,
.ant-pagination-next {
width: 20px;
height: 20px;
min-width: 20px;
line-height: 17px;
color: @border-color-shallow-dark;
border: 1px solid;
}
min-width: 20px;
line-height: 20px;
color: @border-color-shallow-dark;
border: 1px solid;
}
.ant-pagination-prev:hover,
.ant-pagination-next:hover,
.ant-pagination-item:focus,
.ant-pagination-item:hover {
color: @primary-color;
border: 1px solid @primary-color;
}
.ant-pagination-prev:hover,
.ant-pagination-next:hover,
.ant-pagination-item:focus,
.ant-pagination-item:hover {
color: @primary-color;
border: 1px solid @primary-color;
}
.ant-pagination-item {
height: 20px;
min-width: 20px;
margin: 0 3px;
line-height: 20px;
.ant-pagination-item {
height: 20px;
min-width: 20px;
margin: 0 3px;
line-height: 20px;
&:last-child {
margin-right: 0 !important;
}
&:last-child {
margin-right: 0 !important;
}
}
.ant-pagination-item-active {
background: @primary-color;
.ant-pagination-item-active {
background: @primary-color;
a {
color: @white;
}
}
.ant-pagination-options {
margin-left: 20px;
a {
color: @white;
}
}
.ant-select-sm .ant-select-selection--single
{
heigh
t: 20px;
}
.ant-pagination-options
{
margin-lef
t: 20px;
}
.ant-pagination-options,
.ant-pagination-total-text,
.ant-pagination-options-quick-jumper {
height: 20px;
line-height: 20px;
}
.ant-select-sm .ant-select-selection--single {
height: 20px;
}
.ant-select-selection__rendered {
height: 18px;
line-height: 18px;
}
.ant-pagination-options,
.ant-pagination-total-text,
.ant-pagination-options-quick-jumper {
height: 20px;
line-height: 20px;
}
.ant-pagination-total-text,
.ant-select-selection__rendered,
.ant-select-dropdown-menu-item,
.ant-pagination-options-quick-jumper {
font-size: 13px;
}
.ant-select-selection__rendered {
height: 18px;
line-height: 18px;
}
.ant-pagination-options-quick-jumper input {
width: 40px;
height: 20px;
margin: 0 6px;
line-height: 20px;
text-align: center;
}
.ant-pagination-total-text,
.ant-select-selection__rendered,
.ant-select-dropdown-menu-item,
.ant-pagination-options-quick-jumper {
font-size: 13px;
}
.ant-pagination-jump-prev,
.ant-pagination-jump-next {
height: 20px;
line-height: 20px;
}
.ant-pagination-options-quick-jumper input {
width: 40px;
height: 20px;
margin: 0 6px;
line-height: 20px;
text-align: center;
}
.ant-pagination-options-size-changer.ant-select {
margin-right: 20px;
}
.ant-pagination-jump-prev,
.ant-pagination-jump-next {
height: 20px;
line-height: 20px;
}
.ant-select-arrow {
color: @border-color-shallow-dark;
}
.ant-pagination-options-size-changer.ant-select {
margin-right: 20px;
}
&-disabled
{
display: none
;
.ant-select-arrow
{
color: @border-color-shallow-dark
;
}
}
&-disabled {
display: none;
}
}
src/layouts/default/LayoutContent.tsx
View file @
faf3f460
...
...
@@ -6,17 +6,23 @@ import { ContentEnum } from '/@/enums/appEnum';
import
{
appStore
}
from
'
/@/store/modules/app
'
;
// import { RouterView } from 'vue-router';
import
PageLayout
from
'
/@/layouts/page/index
'
;
import
FrameLayout
from
'
/@/layouts/iframe/index.vue
'
;
import
{
useSetting
}
from
'
/@/hooks/core/useSetting
'
;
export
default
defineComponent
({
name
:
'
DefaultLayoutContent
'
,
setup
()
{
const
{
projectSetting
}
=
useSetting
();
return
()
=>
{
const
{
getProjectConfig
}
=
appStore
;
const
{
contentMode
}
=
getProjectConfig
;
const
wrapClass
=
contentMode
===
ContentEnum
.
FULL
?
'
full
'
:
'
fixed
'
;
return
(
<
Layout
.
Content
class=
{
`layout-content ${wrapClass} `
}
>
{
{
default
:
()
=>
<
PageLayout
/>
,
default
:
()
=>
[<
PageLayout
/>,
projectSetting
.
canEmbedIFramePage
&&
<
FrameLayout
/>]
,
}
}
</
Layout
.
Content
>
);
...
...
src/layouts/page/index.tsx
View file @
faf3f460
...
...
@@ -6,9 +6,7 @@ import { useTransition } from './useTransition';
import
{
RouterView
,
RouteLocation
}
from
'
vue-router
'
;
import
{
tabStore
}
from
'
/@/store/modules/tab
'
;
import
FrameLayout
from
'
/@/layouts/iframe/index.vue
'
;
import
{
useSetting
}
from
'
/@/hooks/core/useSetting
'
;
// import { useRouter } from 'vue-router';
export
default
defineComponent
({
name
:
'
PageLayout
'
,
...
...
@@ -24,7 +22,6 @@ export default defineComponent({
const
{
on
:
transitionOn
}
=
useTransition
();
on
=
transitionOn
;
}
const
{
projectSetting
}
=
useSetting
();
return
()
=>
{
const
{
routerTransition
,
...
...
@@ -35,35 +32,32 @@ export default defineComponent({
const
openCache
=
openKeepAlive
&&
show
;
const
cacheTabs
=
toRaw
(
tabStore
.
getKeepAliveTabsState
)
as
string
[];
return
(
<
div
>
<
RouterView
>
{
{
default
:
({
Component
,
route
}:
{
Component
:
any
;
route
:
RouteLocation
})
=>
{
const
Content
=
openCache
?
(
<
KeepAlive
max=
{
max
}
include=
{
cacheTabs
}
>
<
Component
{
...
route
.
params
}
/>
</
KeepAlive
>
)
:
(
return
[
<
RouterView
>
{
{
default
:
({
Component
,
route
}:
{
Component
:
any
;
route
:
RouteLocation
})
=>
{
const
Content
=
openCache
?
(
<
KeepAlive
max=
{
max
}
include=
{
cacheTabs
}
>
<
Component
{
...
route
.
params
}
/>
);
return
openRouterTransition
?
(
<
Transition
{
...
on
}
name=
{
route
.
meta
.
transitionName
||
routerTransition
}
mode=
"out-in"
>
{
()
=>
Content
}
</
Transition
>
)
:
(
Content
);
},
}
}
</
RouterView
>
{
projectSetting
.
canEmbedIFramePage
&&
<
FrameLayout
/>
}
</
div
>
);
</
KeepAlive
>
)
:
(
<
Component
{
...
route
.
params
}
/>
);
return
openRouterTransition
?
(
<
Transition
{
...
on
}
name=
{
route
.
meta
.
transitionName
||
routerTransition
}
mode=
"out-in"
>
{
()
=>
Content
}
</
Transition
>
)
:
(
Content
);
},
}
}
</
RouterView
>,
];
};
},
});
src/router/guard/progressGuard.ts
View file @
faf3f460
...
...
@@ -3,10 +3,10 @@ import type { Router } from 'vue-router';
import
NProgress
from
'
nprogress
'
;
import
'
nprogress/nprogress.css
'
;
NProgress
.
inc
(
0.4
);
NProgress
.
configure
({
easing
:
'
ease
'
,
speed
:
1000
,
showSpinner
:
false
});
export
function
createProgressGuard
(
router
:
Router
)
{
NProgress
.
inc
(
0.1
);
NProgress
.
configure
({
easing
:
'
ease
'
,
speed
:
200
,
showSpinner
:
false
});
router
.
beforeEach
(
async
()
=>
{
NProgress
.
start
();
return
true
;
...
...
src/router/menus/modules/demo/comp.ts
View file @
faf3f460
...
...
@@ -17,6 +17,68 @@ const menu: MenuModule = {
path
:
'
/click-out-side
'
,
name
:
'
ClickOutSide组件
'
,
},
{
path
:
'
/table
'
,
name
:
'
表格组件
'
,
children
:
[
{
path
:
'
/basic
'
,
name
:
'
基础表格
'
,
},
{
path
:
'
/treeTable
'
,
name
:
'
树形表格
'
,
},
{
path
:
'
/fetchTable
'
,
name
:
'
远程加载
'
,
},
{
path
:
'
/fixedColumn
'
,
name
:
'
固定列
'
,
},
{
path
:
'
/customerCell
'
,
name
:
'
自定义列
'
,
},
{
path
:
'
/formTable
'
,
name
:
'
开启搜索区域
'
,
},
{
path
:
'
/useTable
'
,
name
:
'
UseTable
'
,
},
{
path
:
'
/refTable
'
,
name
:
'
RefTable
'
,
},
{
path
:
'
/multipleHeader
'
,
name
:
'
多级表头
'
,
},
{
path
:
'
/mergeHeader
'
,
name
:
'
合并表头
'
,
},
{
path
:
'
/expandTable
'
,
name
:
'
可展开表格
'
,
},
{
path
:
'
/fixedHeight
'
,
name
:
'
定高/头部自定义
'
,
},
{
path
:
'
/footerTable
'
,
name
:
'
表尾行合计
'
,
},
{
path
:
'
/editCellTable
'
,
name
:
'
可编辑单元格
'
,
},
],
},
{
path
:
'
/form
'
,
name
:
'
表单组件
'
,
...
...
src/router/routes/modules/demo/comp.ts
View file @
faf3f460
...
...
@@ -98,6 +98,128 @@ export default {
},
],
},
{
path
:
'
/table
'
,
name
:
'
TableDemo
'
,
redirect
:
'
/comp/table/basic
'
,
meta
:
{
title
:
'
表格组件
'
,
},
children
:
[
{
path
:
'
basic
'
,
name
:
'
TableBasicDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/Basic.vue
'
),
meta
:
{
title
:
'
基础表格
'
,
},
},
{
path
:
'
treeTable
'
,
name
:
'
TreeTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/TreeTable.vue
'
),
meta
:
{
title
:
'
树形表格
'
,
},
},
{
path
:
'
fetchTable
'
,
name
:
'
FetchTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/FetchTable.vue
'
),
meta
:
{
title
:
'
远程加载示例
'
,
},
},
{
path
:
'
fixedColumn
'
,
name
:
'
FixedColumnDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/FixedColumn.vue
'
),
meta
:
{
title
:
'
固定列
'
,
},
},
{
path
:
'
customerCell
'
,
name
:
'
CustomerCellDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/CustomerCell.vue
'
),
meta
:
{
title
:
'
自定义列
'
,
},
},
{
path
:
'
formTable
'
,
name
:
'
FormTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/FormTable.vue
'
),
meta
:
{
title
:
'
开启搜索区域
'
,
},
},
{
path
:
'
useTable
'
,
name
:
'
UseTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/UseTable.vue
'
),
meta
:
{
title
:
'
UseTable
'
,
},
},
{
path
:
'
refTable
'
,
name
:
'
RefTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/RefTable.vue
'
),
meta
:
{
title
:
'
RefTable
'
,
},
},
{
path
:
'
multipleHeader
'
,
name
:
'
MultipleHeaderDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/MultipleHeader.vue
'
),
meta
:
{
title
:
'
多级表头
'
,
},
},
{
path
:
'
mergeHeader
'
,
name
:
'
MergeHeaderDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/MergeHeader.vue
'
),
meta
:
{
title
:
'
合并表头
'
,
},
},
{
path
:
'
expandTable
'
,
name
:
'
ExpandTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/ExpandTable.vue
'
),
meta
:
{
title
:
'
可展开表格
'
,
},
},
{
path
:
'
fixedHeight
'
,
name
:
'
FixedHeightDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/FixedHeight.vue
'
),
meta
:
{
title
:
'
定高/头部自定义
'
,
},
},
{
path
:
'
footerTable
'
,
name
:
'
FooterTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/FooterTable.vue
'
),
meta
:
{
title
:
'
表尾行合计
'
,
},
},
{
path
:
'
editCellTable
'
,
name
:
'
EditCellTableDemo
'
,
component
:
()
=>
import
(
'
/@/views/demo/table/EditCellTable.vue
'
),
meta
:
{
title
:
'
可编辑单元格
'
,
},
},
],
},
{
path
:
'
/tree
'
,
name
:
'
TreeDemo
'
,
...
...
src/store/index.ts
View file @
faf3f460
import
type
{
App
}
from
'
vue
'
;
import
{
createStore
,
createLogger
,
Plugin
}
from
'
vuex
'
;
import
{
createStore
,
// createLogger, Plugin
}
from
'
vuex
'
;
import
{
config
}
from
'
vuex-module-decorators
'
;
import
{
isDevMode
}
from
'
/@/utils/env
'
;
config
.
rawError
=
true
;
const
isDev
=
isDevMode
();
const
plugins
:
Plugin
<
any
>
[]
=
isDev
?
[
createLogger
()]
:
[];
//
const plugins: Plugin<any>[] = isDev ? [createLogger()] : [];
const
store
=
createStore
({
modules
:
{},
strict
:
isDev
,
plugins
,
//
plugins,
});
export
function
setupStore
(
app
:
App
<
Element
>
)
{
app
.
use
(
store
);
...
...
src/types/source.d.ts
View file @
faf3f460
declare
module
'
ant-design-vue/es/locale/zh_CN
'
;
declare
module
'
vue-draggable-resizable
'
;
declare
const
React
:
string
;
declare
module
'
*.bmp
'
{
const
src
:
string
;
...
...
src/useApp.tsx
View file @
faf3f460
...
...
@@ -2,8 +2,6 @@ import type { ProjectConfig } from '/@/types/config';
import
{
computed
,
ref
}
from
'
vue
'
;
import
{
BasicEmpty
}
from
'
/@/components/Basic
'
;
import
{
ThemeModeEnum
}
from
'
/@/enums/appEnum
'
;
import
{
PROJ_CFG_KEY
}
from
'
/@/enums/cacheEnum
'
;
...
...
@@ -59,10 +57,6 @@ export function useInitAppConfigStore() {
// Config Provider
export
function
useConfigProvider
()
{
function
renderEmpty
()
{
return
<
BasicEmpty
/>;
}
function
transformCellText
({
text
}:
{
text
:
string
})
{
if
(
isNull
(
text
)
||
isUnDef
(
text
))
{
return
'
-
'
;
...
...
@@ -70,7 +64,6 @@ export function useConfigProvider() {
return
text
;
}
return
{
renderEmpty
,
transformCellText
,
};
}
...
...
src/views/demo/comp/verify/index.vue
View file @
faf3f460
...
...
@@ -25,7 +25,7 @@
<div
class=
"flex justify-center p-4 items-center bg-gray-700"
>
<BasicDragVerify
ref=
"el4"
@
success=
"handleSuccess"
>
<template
v-slot:
actionIcon=
"isPassing"
>
<template
#
actionIcon
="
isPassing
"
>
<BugOutlined
v-if=
"isPassing"
/>
<RightOutlined
v-else
/>
</
template
>
...
...
@@ -35,7 +35,7 @@
<div
class=
"flex justify-center p-4 items-center bg-gray-700"
>
<BasicDragVerify
ref=
"el5"
@
success=
"handleSuccess"
>
<
template
v-slot:
text=
"isPassing"
>
<
template
#
text
="
isPassing
"
>
<div
v-if=
"isPassing"
>
<BugOutlined
/>
成功
...
...
src/views/demo/table/Basic.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
title=
"基础示例"
titleHelpMessage=
"温馨提醒"
:columns=
"columns"
:dataSource=
"data"
:canResize=
"canResize"
:loading=
"loading"
:striped=
"striped"
:bordered=
"border"
:pagination=
"
{ pageSize: 20 }"
>
<template
#toolbar
>
<a-button
type=
"primary"
@
click=
"toggleCanResize"
>
{{
!
canResize
?
'
自适应高度
'
:
'
取消自适应
'
}}
</a-button>
<a-button
type=
"primary"
@
click=
"toggleBorder"
>
{{
!
border
?
'
显示边框
'
:
'
隐藏边框
'
}}
</a-button>
<a-button
type=
"primary"
@
click=
"toggleLoading"
>
开启loading
</a-button>
<a-button
type=
"primary"
@
click=
"toggleStriped"
>
{{
!
striped
?
'
显示斑马纹
'
:
'
隐藏斑马纹
'
}}
</a-button>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
ref
}
from
'
vue
'
;
import
{
BasicTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
,
getBasicData
}
from
'
./tableData
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
canResize
=
ref
(
false
);
const
loading
=
ref
(
false
);
const
striped
=
ref
(
true
);
const
border
=
ref
(
true
);
function
toggleCanResize
()
{
canResize
.
value
=
!
canResize
.
value
;
}
function
toggleStriped
()
{
striped
.
value
=
!
striped
.
value
;
}
function
toggleLoading
()
{
loading
.
value
=
true
;
setTimeout
(()
=>
{
loading
.
value
=
false
;
},
3000
);
}
function
toggleBorder
()
{
border
.
value
=
!
border
.
value
;
}
return
{
columns
:
getBasicColumns
(),
data
:
getBasicData
(),
canResize
,
loading
,
striped
,
border
,
toggleStriped
,
toggleCanResize
,
toggleLoading
,
toggleBorder
,
};
},
});
</
script
>
src/views/demo/table/CustomerCell.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
>
<template
#id
="
{ record }"> ID:
{{
record
.
id
}}
</
template
>
<
template
#no
="{
record
}"
><Tag
color=
"green"
>
{{
record
.
no
}}
</Tag>
</
template
>
<
template
#img
>
<TableImg
:imgList=
"['https://picsum.photos/id/66/346/216', 'https://picsum.photos/id/67/346/216']"
/>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
,
BasicColumn
,
TableImg
}
from
'
/@/components/Table
'
;
import
{
Tag
}
from
'
ant-design-vue
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
const
columns
:
BasicColumn
[]
=
[
{
title
:
'
ID
'
,
dataIndex
:
'
id
'
,
slots
:
{
customRender
:
'
id
'
},
},
{
title
:
'
姓名
'
,
dataIndex
:
'
name
'
,
width
:
120
,
},
{
title
:
'
头像
'
,
dataIndex
:
'
img
'
,
width
:
120
,
slots
:
{
customRender
:
'
img
'
},
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
},
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
slots
:
{
customRender
:
'
no
'
},
},
{
title
:
'
开始时间
'
,
dataIndex
:
'
beginTime
'
,
},
{
title
:
'
结束时间
'
,
dataIndex
:
'
endTime
'
,
},
];
export
default
defineComponent
({
components
:
{
BasicTable
,
TableImg
,
Tag
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
自定义列内容
'
,
api
:
demoListApi
,
columns
:
columns
,
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/EditCellTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
>
<template
#customId
>
<EditTableHeaderIcon
title=
"Id"
/>
</
template
>
<
template
#customName
>
<EditTableHeaderIcon
title=
"姓名"
/>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
,
BasicColumn
,
renderEditableCell
,
EditTableHeaderIcon
,
}
from
'
/@/components/Table
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
const
columns
:
BasicColumn
[]
=
[
{
// title: 'ID',
dataIndex
:
'
id
'
,
slots
:
{
title
:
'
customId
'
},
customRender
:
renderEditableCell
({
dataIndex
:
'
id
'
}),
},
{
// title: '姓名',
dataIndex
:
'
name
'
,
slots
:
{
title
:
'
customName
'
},
customRender
:
renderEditableCell
({
dataIndex
:
'
name
'
,
}),
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
sorter
:
true
,
},
];
export
default
defineComponent
({
components
:
{
BasicTable
,
EditTableHeaderIcon
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
可编辑单元格示例
'
,
api
:
demoListApi
,
columns
:
columns
,
showIndexColumn
:
false
,
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/ExpandTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
>
<template
#expandedRowRender
="
{ record }">
<span>
No:
{{
record
.
no
}}
</span>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
}
from
'
./tableData
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
可展开表格
'
,
api
:
demoListApi
,
titleHelpMessage
:
'
不能与scroll共用
'
,
columns
:
getBasicColumns
(),
rowKey
:
'
id
'
,
canResize
:
false
,
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/FetchTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
>
<template
#toolbar
>
<a-button
type=
"primary"
@
click=
"handleReloadCurrent"
>
刷新当前页
</a-button>
<a-button
type=
"primary"
@
click=
"handleReload"
>
刷新并返回第一页
</a-button>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
}
from
'
./tableData
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
[
registerTable
,
{
reload
}]
=
useTable
({
title
:
'
远程加载示例
'
,
api
:
demoListApi
,
columns
:
getBasicColumns
(),
});
function
handleReloadCurrent
()
{
reload
();
// reload({
// searchInfo: 'xxx',
// });
}
function
handleReload
()
{
reload
({
page
:
1
,
});
}
return
{
registerTable
,
handleReloadCurrent
,
handleReload
,
};
},
});
</
script
>
src/views/demo/table/FixedColumn.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
>
<template
#action
>
<TableAction
:actions=
"[
{
label: '删除',
props: {
onClick: handleDelete,
},
},
]"
:dropDownActions="[
{
label: '启用',
props: {
onClick: handleOpen,
},
},
]"
/>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
,
BasicColumn
,
TableAction
}
from
'
/@/components/Table
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
const
columns
:
BasicColumn
[]
=
[
{
title
:
'
ID
'
,
dataIndex
:
'
id
'
,
fixed
:
'
left
'
,
width
:
280
,
},
{
title
:
'
姓名
'
,
dataIndex
:
'
name
'
,
width
:
260
,
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
width
:
260
,
},
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
width
:
300
,
},
{
title
:
'
开始时间
'
,
width
:
200
,
dataIndex
:
'
beginTime
'
,
},
{
title
:
'
结束时间
'
,
dataIndex
:
'
endTime
'
,
width
:
200
,
},
];
export
default
defineComponent
({
components
:
{
BasicTable
,
TableAction
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
TableAction组件及固定列示例
'
,
api
:
demoListApi
,
columns
:
columns
,
rowSelection
:
{
type
:
'
radio
'
},
actionColumn
:
{
width
:
160
,
title
:
'
Action
'
,
dataIndex
:
'
action
'
,
slots
:
{
customRender
:
'
action
'
},
},
});
function
handleDelete
()
{
console
.
log
(
'
点击了删除
'
);
}
function
handleOpen
()
{
console
.
log
(
'
点击了启用
'
);
}
return
{
registerTable
,
handleDelete
,
handleOpen
,
};
},
});
</
script
>
src/views/demo/table/FixedHeight.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
>
<template
#customTitle
>
<span>
姓名
<BaseHelp
class=
"ml-2"
text=
"姓名"
/>
</span>
</
template
>
<
template
#customAddress
>
地址
<FormOutlined
class=
"ml-2"
/>
</
template
>
</BasicTable>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getCustomHeaderColumns
}
from
'
./tableData
'
;
import
{
FormOutlined
}
from
'
@ant-design/icons-vue
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
,
FormOutlined
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
定高/头部自定义
'
,
api
:
demoListApi
,
columns
:
getCustomHeaderColumns
(),
canResize
:
false
,
scroll
:
{
y
:
100
},
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/FooterTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
}
from
'
./tableData
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
function
handleSummary
(
tableData
:
any
[])
{
const
totalNo
=
tableData
.
reduce
((
prev
,
next
)
=>
{
prev
+=
next
.
no
;
return
prev
;
},
0
);
return
[
{
_row
:
'
合计
'
,
_index
:
'
平均值
'
,
no
:
totalNo
,
},
{
_row
:
'
合计
'
,
_index
:
'
平均值
'
,
no
:
totalNo
,
},
];
}
const
[
registerTable
]
=
useTable
({
title
:
'
表尾行合计示例
'
,
api
:
demoListApi
,
rowSelection
:
{
type
:
'
checkbox
'
},
columns
:
getBasicColumns
(),
showSummary
:
true
,
summaryFunc
:
handleSummary
,
scroll
:
{
x
:
2000
},
canResize
:
false
,
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/FormTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<BasicTable
@
register=
"registerTable"
/>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
,
getFormConfig
}
from
'
./tableData
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
开启搜索区域
'
,
api
:
demoListApi
,
columns
:
getBasicColumns
(),
useSearchForm
:
true
,
formConfig
:
getFormConfig
(),
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/MergeHeader.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getMergeHeaderColumns
}
from
'
./tableData
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
多级表头示例
'
,
api
:
demoListApi
,
columns
:
getMergeHeaderColumns
(),
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/MultipleHeader.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
@
register=
"registerTable"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getMultipleHeaderColumns
}
from
'
./tableData
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
[
registerTable
]
=
useTable
({
title
:
'
多级表头示例
'
,
api
:
demoListApi
,
columns
:
getMultipleHeaderColumns
(),
});
return
{
registerTable
,
};
},
});
</
script
>
src/views/demo/table/RefTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<div
class=
"mb-4"
>
<a-button
class=
"mr-2"
@
click=
"reloadTable"
>
还原
</a-button>
<a-button
class=
"mr-2"
@
click=
"changeLoading"
>
开启loading
</a-button>
<a-button
class=
"mr-2"
@
click=
"changeColumns"
>
更改Columns
</a-button>
<a-button
class=
"mr-2"
@
click=
"getColumn"
>
获取Columns
</a-button>
<a-button
class=
"mr-2"
@
click=
"getTableData"
>
获取表格数据
</a-button>
<a-button
class=
"mr-2"
@
click=
"setPaginationInfo"
>
跳转到第2页
</a-button>
</div>
<div
class=
"mb-4"
>
<a-button
class=
"mr-2"
@
click=
"getSelectRowList"
>
获取选中行
</a-button>
<a-button
class=
"mr-2"
@
click=
"getSelectRowKeyList"
>
获取选中行Key
</a-button>
<a-button
class=
"mr-2"
@
click=
"setSelectedRowKeyList"
>
设置选中行
</a-button>
<a-button
class=
"mr-2"
@
click=
"clearSelect"
>
清空选中行
</a-button>
<a-button
class=
"mr-2"
@
click=
"getPagination"
>
获取分页信息
</a-button>
</div>
<BasicTable
:canResize=
"false"
title=
"RefTable示例"
titleHelpMessage=
"使用Ref调用表格内方法"
ref=
"tableRef"
:api=
"api"
:columns=
"columns"
rowKey=
"id"
:rowSelection=
"
{ type: 'checkbox' }"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
,
ref
,
unref
}
from
'
vue
'
;
import
{
BasicTable
,
TableActionType
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
,
getBasicShortColumns
}
from
'
./tableData
'
;
import
{
useMessage
}
from
'
/@/hooks/web/useMessage
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
tableRef
=
ref
<
Nullable
<
TableActionType
>>
(
null
);
const
{
createMessage
}
=
useMessage
();
function
getTableAction
()
{
const
tableAction
=
unref
(
tableRef
);
if
(
!
tableAction
)
{
throw
new
Error
(
'
tableAction is null
'
);
}
return
tableAction
;
}
function
changeLoading
()
{
getTableAction
().
setLoading
(
true
);
setTimeout
(()
=>
{
getTableAction
().
setLoading
(
false
);
},
1000
);
}
function
changeColumns
()
{
getTableAction
().
setColumns
(
getBasicShortColumns
());
}
function
reloadTable
()
{
getTableAction
().
setColumns
(
getBasicColumns
());
getTableAction
().
reload
({
page
:
1
,
});
}
function
getColumn
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getTableAction
().
getColumns
());
}
function
getTableData
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getTableAction
().
getDataSource
());
}
function
getPagination
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getTableAction
().
getPaginationRef
());
}
function
setPaginationInfo
()
{
getTableAction
().
setPagination
({
current
:
2
,
});
getTableAction
().
reload
();
}
function
getSelectRowList
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getTableAction
().
getSelectRows
());
}
function
getSelectRowKeyList
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getTableAction
().
getSelectRowKeys
());
}
function
setSelectedRowKeyList
()
{
getTableAction
().
setSelectedRowKeys
([
'
0
'
,
'
1
'
,
'
2
'
]);
}
function
clearSelect
()
{
getTableAction
().
clearSelectedRowKeys
();
}
return
{
tableRef
,
api
:
demoListApi
,
columns
:
getBasicColumns
(),
changeLoading
,
changeColumns
,
reloadTable
,
getColumn
,
getTableData
,
getPagination
,
setPaginationInfo
,
getSelectRowList
,
getSelectRowKeyList
,
setSelectedRowKeyList
,
clearSelect
,
};
},
});
</
script
>
src/views/demo/table/TreeTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<BasicTable
:rowSelection=
"
{ type: 'checkbox' }"
:isTreeTable="true"
title="树形表格"
titleHelpMessage="树形组件不能和序列号列同时存在"
:columns="columns"
:dataSource="data"
rowKey="id"
:indentSize="20"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
,
getTreeTableData
}
from
'
./tableData
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
return
{
columns
:
getBasicColumns
(),
data
:
getTreeTableData
(),
};
},
});
</
script
>
src/views/demo/table/UseTable.vue
0 → 100644
View file @
faf3f460
<
template
>
<div
class=
"p-4"
>
<div
class=
"mb-4"
>
<a-button
class=
"mr-2"
@
click=
"reloadTable"
>
还原
</a-button>
<a-button
class=
"mr-2"
@
click=
"changeLoading"
>
开启loading
</a-button>
<a-button
class=
"mr-2"
@
click=
"changeColumns"
>
更改Columns
</a-button>
<a-button
class=
"mr-2"
@
click=
"getColumn"
>
获取Columns
</a-button>
<a-button
class=
"mr-2"
@
click=
"getTableData"
>
获取表格数据
</a-button>
<a-button
class=
"mr-2"
@
click=
"setPaginationInfo"
>
跳转到第2页
</a-button>
</div>
<div
class=
"mb-4"
>
<a-button
class=
"mr-2"
@
click=
"getSelectRowList"
>
获取选中行
</a-button>
<a-button
class=
"mr-2"
@
click=
"getSelectRowKeyList"
>
获取选中行Key
</a-button>
<a-button
class=
"mr-2"
@
click=
"setSelectedRowKeyList"
>
设置选中行
</a-button>
<a-button
class=
"mr-2"
@
click=
"clearSelect"
>
清空选中行
</a-button>
<a-button
class=
"mr-2"
@
click=
"getPagination"
>
获取分页信息
</a-button>
</div>
<BasicTable
@
register=
"registerTable"
/>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'
vue
'
;
import
{
BasicTable
,
useTable
}
from
'
/@/components/Table
'
;
import
{
getBasicColumns
,
getBasicShortColumns
}
from
'
./tableData
'
;
import
{
useMessage
}
from
'
/@/hooks/web/useMessage
'
;
import
{
demoListApi
}
from
'
/@/api/demo/table
'
;
export
default
defineComponent
({
components
:
{
BasicTable
},
setup
()
{
const
{
createMessage
}
=
useMessage
();
const
[
registerTable
,
{
setLoading
,
setColumns
,
getColumns
,
getDataSource
,
reload
,
getPaginationRef
,
setPagination
,
getSelectRows
,
getSelectRowKeys
,
setSelectedRowKeys
,
clearSelectedRowKeys
,
},
]
=
useTable
({
canResize
:
false
,
title
:
'
useTable示例
'
,
titleHelpMessage
:
'
使用useTable调用表格内方法
'
,
api
:
demoListApi
,
columns
:
getBasicColumns
(),
rowKey
:
'
id
'
,
rowSelection
:
{
type
:
'
checkbox
'
,
},
});
function
changeLoading
()
{
setLoading
(
true
);
setTimeout
(()
=>
{
setLoading
(
false
);
},
1000
);
}
function
changeColumns
()
{
setColumns
(
getBasicShortColumns
());
}
function
reloadTable
()
{
setColumns
(
getBasicColumns
());
reload
({
page
:
1
,
});
}
function
getColumn
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getColumns
());
}
function
getTableData
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getDataSource
());
}
function
getPagination
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getPaginationRef
());
}
function
setPaginationInfo
()
{
setPagination
({
current
:
2
,
});
reload
();
}
function
getSelectRowList
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getSelectRows
());
}
function
getSelectRowKeyList
()
{
createMessage
.
info
(
'
请在控制台查看!
'
);
console
.
log
(
getSelectRowKeys
());
}
function
setSelectedRowKeyList
()
{
setSelectedRowKeys
([
'
0
'
,
'
1
'
,
'
2
'
]);
}
function
clearSelect
()
{
clearSelectedRowKeys
();
}
return
{
registerTable
,
changeLoading
,
changeColumns
,
reloadTable
,
getColumn
,
getTableData
,
getPagination
,
setPaginationInfo
,
getSelectRowList
,
getSelectRowKeyList
,
setSelectedRowKeyList
,
clearSelect
,
};
},
});
</
script
>
src/views/demo/table/tableData.tsx
0 → 100644
View file @
faf3f460
import
{
FormProps
,
FormSchema
}
from
'
/@/components/Table
'
;
import
{
BasicColumn
}
from
'
/@/components/Table/src/types/table
'
;
export
function
getBasicColumns
():
BasicColumn
[]
{
return
[
{
title
:
'
ID
'
,
width
:
150
,
dataIndex
:
'
id
'
,
},
{
title
:
'
姓名
'
,
dataIndex
:
'
name
'
,
width
:
120
,
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
},
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
width
:
80
,
},
{
title
:
'
开始时间
'
,
dataIndex
:
'
beginTime
'
,
},
{
title
:
'
结束时间
'
,
sorter
:
true
,
dataIndex
:
'
endTime
'
,
},
];
}
export
function
getBasicShortColumns
():
BasicColumn
[]
{
return
[
{
title
:
'
ID
'
,
width
:
150
,
dataIndex
:
'
id
'
,
},
{
title
:
'
姓名
'
,
dataIndex
:
'
name
'
,
width
:
120
,
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
},
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
width
:
80
,
},
];
}
export
function
getMultipleHeaderColumns
():
BasicColumn
[]
{
return
[
{
title
:
'
ID
'
,
dataIndex
:
'
id
'
,
width
:
200
,
},
{
title
:
'
姓名
'
,
dataIndex
:
'
name
'
,
width
:
120
,
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
sorter
:
true
,
children
:
[
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
width
:
120
,
filters
:
[
{
text
:
'
Male
'
,
value
:
'
male
'
},
{
text
:
'
Female
'
,
value
:
'
female
'
},
],
},
{
title
:
'
开始时间
'
,
dataIndex
:
'
beginTime
'
,
width
:
120
,
},
{
title
:
'
结束时间
'
,
dataIndex
:
'
endTime
'
,
width
:
120
,
},
],
},
];
}
export
function
getCustomHeaderColumns
():
BasicColumn
[]
{
return
[
{
title
:
'
ID
'
,
dataIndex
:
'
id
'
,
width
:
200
,
},
{
// title: '姓名',
dataIndex
:
'
name
'
,
width
:
120
,
slots
:
{
title
:
'
customTitle
'
},
},
{
// title: '地址',
dataIndex
:
'
address
'
,
slots
:
{
title
:
'
customAddress
'
},
sorter
:
true
,
},
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
width
:
120
,
filters
:
[
{
text
:
'
Male
'
,
value
:
'
male
'
},
{
text
:
'
Female
'
,
value
:
'
female
'
},
],
},
{
title
:
'
开始时间
'
,
dataIndex
:
'
beginTime
'
,
width
:
120
,
},
{
title
:
'
结束时间
'
,
dataIndex
:
'
endTime
'
,
width
:
120
,
},
];
}
const
renderContent
=
({
text
,
index
}:
{
text
:
any
;
index
:
number
})
=>
{
const
obj
:
any
=
{
children
:
text
,
attrs
:
{},
};
if
(
index
===
9
)
{
obj
.
attrs
.
colSpan
=
0
;
}
return
obj
;
};
export
function
getMergeHeaderColumns
():
BasicColumn
[]
{
return
[
{
title
:
'
ID
'
,
dataIndex
:
'
id
'
,
width
:
300
,
customRender
:
renderContent
,
},
{
title
:
'
姓名
'
,
dataIndex
:
'
name
'
,
width
:
300
,
customRender
:
renderContent
,
},
{
title
:
'
地址
'
,
dataIndex
:
'
address
'
,
colSpan
:
2
,
width
:
120
,
sorter
:
true
,
customRender
:
({
text
,
index
}:
{
text
:
any
;
index
:
number
})
=>
{
const
obj
:
any
=
{
children
:
text
,
attrs
:
{},
};
if
(
index
===
2
)
{
obj
.
attrs
.
rowSpan
=
2
;
}
if
(
index
===
3
)
{
obj
.
attrs
.
colSpan
=
0
;
}
return
obj
;
},
},
{
title
:
'
编号
'
,
dataIndex
:
'
no
'
,
colSpan
:
0
,
filters
:
[
{
text
:
'
Male
'
,
value
:
'
male
'
},
{
text
:
'
Female
'
,
value
:
'
female
'
},
],
customRender
:
renderContent
,
},
{
title
:
'
开始时间
'
,
dataIndex
:
'
beginTime
'
,
width
:
200
,
customRender
:
renderContent
,
},
{
title
:
'
结束时间
'
,
dataIndex
:
'
endTime
'
,
width
:
200
,
customRender
:
renderContent
,
},
];
}
export
const
getAdvanceSchema
=
(
itemNumber
=
6
):
FormSchema
[]
=>
{
const
arr
:
any
=
[];
for
(
let
index
=
0
;
index
<
itemNumber
;
index
++
)
{
arr
.
push
({
field
:
`field
${
index
}
`
,
label
:
`字段
${
index
}
`
,
component
:
'
Input
'
,
colProps
:
{
xl
:
12
,
xxl
:
8
,
},
});
}
return
arr
;
};
export
function
getFormConfig
():
Partial
<
FormProps
>
{
return
{
labelWidth
:
100
,
schemas
:
getAdvanceSchema
(
6
),
};
}
export
function
getBasicData
()
{
const
data
:
any
=
(()
=>
{
const
arr
:
any
=
[];
for
(
let
index
=
0
;
index
<
40
;
index
++
)
{
arr
.
push
({
id
:
`
${
index
}
`
,
name
:
'
John Brown
'
,
age
:
`1
${
index
}
`
,
no
:
`
${
index
+
10
}
`
,
address
:
'
New York No. 1 Lake ParkNew York No. 1 Lake Park
'
,
beginTime
:
new
Date
().
toLocaleString
(),
endTime
:
new
Date
().
toLocaleString
(),
});
}
return
arr
;
})();
return
data
;
}
export
function
getTreeTableData
()
{
const
data
:
any
=
(()
=>
{
const
arr
:
any
=
[];
for
(
let
index
=
0
;
index
<
40
;
index
++
)
{
arr
.
push
({
id
:
`
${
index
}
`
,
name
:
'
John Brown
'
,
age
:
`1
${
index
}
`
,
no
:
`
${
index
+
10
}
`
,
address
:
'
New York No. 1 Lake ParkNew York No. 1 Lake Park
'
,
beginTime
:
new
Date
().
toLocaleString
(),
endTime
:
new
Date
().
toLocaleString
(),
children
:
[
{
id
:
`l2-
${
index
}
`
,
name
:
'
John Brown
'
,
age
:
`1
${
index
}
`
,
no
:
`
${
index
+
10
}
`
,
address
:
'
New York No. 1 Lake ParkNew York No. 1 Lake Park
'
,
beginTime
:
new
Date
().
toLocaleString
(),
endTime
:
new
Date
().
toLocaleString
(),
children
:
[
{
id
:
`l3-
${
index
}
`
,
name
:
'
John Brown
'
,
age
:
`1
${
index
}
`
,
no
:
`
${
index
+
10
}
`
,
address
:
'
New York No. 1 Lake ParkNew York No. 1 Lake Park
'
,
beginTime
:
new
Date
().
toLocaleString
(),
endTime
:
new
Date
().
toLocaleString
(),
},
],
},
],
});
}
return
arr
;
})();
return
data
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment