TSXvue3 + element-ui + tsx 通用表格组件
简介: 基于 vue3 el-table 封装的通用表格组件 的 tsx写法,想要参考模板写法的可以到我另一篇博客喔~
TS vue3.2 vite2 element-plus 通用表格组件封装
话不多说,本组件分为四部分:
1、CommonTable.module.scss 文件为组件样式文件
-
:global {
-
.common-table {
-
.el-table__header,
-
.el-table__body {
-
margin: 0;
-
}
-
.el-table::before {
-
height: 0;
-
}
-
.el-button {
-
padding: 0;
-
border: none;
-
margin: 0 4px;
-
padding: 0 4px 0 8px;
-
border-left: 1px solid #e2e2e2;
-
font-size: 14px;
-
min-height: 14px;
-
&:first-child {
-
border-left: none;
-
}
-
}
-
.el-button .el-button {
-
margin-left: 0;
-
}
-
.btn-right div {
-
margin-right: 5px;
-
}
-
.btn-right div:empty {
-
margin-right: 0px;
-
}
-
//斑马纹表格背景色
-
.el-table .even-row {
-
--el-table-tr-background-color: #f5fafb;
-
}
-
.el-table .odd-row {
-
--el-table-tr-background-color: #ffffff;
-
}
-
.el-table--border::after,
-
.el-table--group::after {
-
width: 0;
-
}
-
.el-table__fixed-right::before,
-
.el-table__fixed::before {
-
background-color: transparent;
-
}
-
.custom-table-header {
-
th {
-
background-color: #fff4d9 ;
-
}
-
}
-
.progress-line {
-
.el-progress-bar__outer {
-
height: 16px ;
-
}
-
.el-progress-bar__outer,
-
.el-progress-bar__inner {
-
border-radius: 0 ;
-
}
-
}
-
.text-no-wrap {
-
cursor: pointer;
-
display: inline;
-
}
-
.el-table {
-
td.el-table__cell div,
-
th.el-table__cell>.cell {
-
font-size: 14px;
-
}
-
th.el-table__cell>.cell {
-
font-weight: normal;
-
}
-
.cell {
-
padding: 0 10px;
-
line-height: 39px;
-
}
-
.el-table__header-wrapper .checkBoxRadio .el-checkbox {
-
display: none;
-
}
-
.el-checkbox {
-
display: flex;
-
align-items: center;
-
justify-content: center;
-
}
-
.table-img {
-
width: 60px;
-
height: 60px;
-
object-fit: cover;
-
padding: 6px 0;
-
display: flex;
-
align-items: center;
-
margin: 0 auto;
-
justify-content: center;
-
}
-
}
-
.el-table--small .el-table__cell {
-
padding: 0;
-
}
-
.el-dropdown-menu__item {
-
padding: 5px 10px ;
-
.el-button {
-
width: 100%;
-
text-align: center;
-
padding: 0 8px;
-
margin: 0;
-
}
-
}
-
.flex-box {
-
display: flex;
-
flex-flow: row nowrap;
-
justify-content: flex-start;
-
.item {
-
margin: 0 10px;
-
}
-
}
-
}
-
}
2、CommonTable.module.ts为组件逻辑文件
-
import {
-
ref,
-
watch,
-
nextTick
-
} from 'vue';
-
-
export default function(props, emit, CommonTable) {
-
const curPageCheck = ref([])
-
watch(() => props.data, () => {
-
if (props.showCheckBox || props.turnRadio) {
-
nextTick(() => {
-
CommonTable.value.clearSelection()
-
curPageCheck.value = []
-
if (props.showCheckBox && props.turnRadio) {
-
props.data.filter((item) => {
-
if (item.id === props.selectedIdArr[0]) {
-
CommonTable.value.toggleRowSelection(item, true)
-
}
-
})
-
} else if (props.showCheckBox) {
-
props.data.filter((item) => {
-
if (props.selectedIdArr.includes(item.id)) {
-
CommonTable.value.toggleRowSelection(item, true)
-
curPageCheck.value.push(item.id)
-
}
-
})
-
}
-
})
-
}
-
}, {
-
immediate: true
-
})
-
watch(() => props.selectedIdArr, (val) => {
-
if (props.showCheckBox || props.turnRadio) {
-
nextTick(() => {
-
CommonTable.value.clearSelection()
-
curPageCheck.value = []
-
if (props.showCheckBox && props.turnRadio) {
-
props.data.filter((item) => {
-
if (item.id === val[0]) {
-
CommonTable.value.toggleRowSelection(item, true)
-
}
-
})
-
} else if (props.showCheckBox) {
-
props.data.filter((item) => {
-
if (val.includes(item.id)) {
-
CommonTable.value.toggleRowSelection(item, true)
-
curPageCheck.value.push(item.id)
-
}
-
})
-
}
-
})
-
}
-
}, {
-
immediate: true
-
})
-
const methods = {
-
/**
-
* prop 单值 或者 数组过滤(此处为针对时间组,不作为通用处理)
-
*/
-
propFilter(prop, row) {
-
const res = prop.reduce((total, cur) => {
-
if (row[cur]) {
-
return (total = row[cur] '~')
-
} else {
-
return ''
-
}
-
}, '')
-
return res ? res.replace(/~$/, '') : ''
-
},
-
handleTableButton(row, type) {
-
emit('operation', row, type);
-
},
-
/**
-
* 后续扩展位
-
* @param {*} methods
-
* @param {*} row
-
*/
-
handleClickon(methods, row) {
-
emit(methods, { methods, row })
-
},
-
handleSelectionChange(val) {
-
if (props.showCheckBox && props.turnRadio) {
-
// 选择项大于1时
-
if (val.length > 1) {
-
const del_row = val.shift()
-
CommonTable.value.toggleRowSelection(del_row, false)
-
}
-
}
-
// 全选
-
if (props.showCheckBox && props.selectedIdArr) {
-
if (props.turnRadio) {
-
emit('handle-selection-change', val)
-
} else {
-
// 一般复选框都是走到这一步
-
emit('handle-selection-change', val)
-
}
-
} else {
-
emit('handle-selection-change', val)
-
}
-
},
-
getRowKeys(row) {
-
return row.id
-
},
-
selectAll(val) {
-
if (props.showCheckBox && props.turnRadio) {
-
// 选择项大于1时
-
if (val.length > 1) {
-
val.length = 1
-
}
-
}
-
emit('handle-selection-change', val)
-
},
-
// 斑马纹表格背景色
-
tabRowClassName({ rowIndex }) {
-
const index = rowIndex 1
-
if (index % 2 === 0) {
-
return 'even-row'
-
} else {
-
return 'odd-row'
-
}
-
},
-
cellClassName({ row, columnIndex }) {
-
if (row.confirmTag === 2 && columnIndex < props.tableLabel.length) {
-
return 'height_light_cell'
-
} else {
-
return ''
-
}
-
},
-
buttonDisabled(item, row) {
-
if (typeof item.disabled === 'function') return item.disabled(row) || false
-
if (!item.disabled) return item.disabled
-
},
-
/**
-
* 单选框选中事件
-
*/
-
rowClick(row) {
-
emit('rowClick', row)
-
}
-
}
-
return {
-
methods
-
}
-
}
3、CommonTable.tsx为组件渲染文件
-
import {
-
defineComponent,
-
ref,
-
PropType
-
} from 'vue';
-
import {
-
TableLabel,
-
TableDataItem
-
} from './types';
-
import useModule from './CommonTable.module';
-
import './CommonTable.module.scss';
-
-
export default defineComponent({
-
name: 'CommonTable',
-
props: {
-
/**
-
* 表格最高高度
-
*/
-
maxHeight: {
-
type: [String, Number],
-
default: 'auto'
-
},
-
/**
-
* 表格自定义属性展示
-
*/
-
tableLabel: {
-
type: Array as PropType<TableLabel[]>,
-
default: () => []
-
},
-
/**
-
* 表格数据源
-
*/
-
data: {
-
type: Array as PropType<TableDataItem[]>,
-
default: () => []
-
},
-
/**
-
* 配置需要显示的操作菜单
-
*/
-
option: {
-
type: Object,
-
default: () => {}
-
},
-
showCheckBox: {
-
// 配置是否显示全选(复选框)
-
type: Boolean,
-
default: false
-
},
-
/**
-
* 是否显示索引
-
*/
-
showIndex: {
-
type: Boolean,
-
default: false
-
},
-
turnRadio: {
-
type: Boolean,
-
default: false
-
},
-
selectedIdArr: {
-
type: Array as PropType<number[] | string[]>,
-
default: () => []
-
},
-
/**
-
* 是否 隐藏文字过长
-
*/
-
overflowText: {
-
type: Boolean,
-
default: false
-
},
-
/**
-
* 加载提示
-
*/
-
loading: {
-
type: Boolean,
-
default: false
-
},
-
/**
-
* 是否保持之前复选框的数据
-
*/
-
keep: {
-
type: Boolean,
-
default: false
-
},
-
/**
-
* 动态绑定 key 值
-
*/
-
keyId: {
-
type: String,
-
default: 'id'
-
},
-
/**
-
* 行内自定义样式配置
-
*/
-
rowStyle: {
-
type: Object,
-
default: () => {
-
return {
-
height: '40px'
-
}
-
}
-
},
-
/**
-
* 是否展示展开按钮
-
*/
-
showExpand: {
-
type: Boolean,
-
default: false
-
}
-
},
-
setup(props, { emit, slots }) {
-
const CommonTable = ref(null)
-
const {
-
methods
-
} = useModule(props, emit, CommonTable)
-
return () => (
-
<div v-loading={props.loading}>
-
<el-table
-
class='common-table'
-
ref={CommonTable}
-
data={props.data}
-
border
-
max-height={props.maxHeight}
-
row-class-name={methods.tabRowClassName}
-
row-style={props.rowStyle}
-
cell-class-name={methods.cellClassName}
-
header-row-class-name='custom-table-header'
-
row-key={props.keyId}
-
on-select={methods.handleSelectionChange}
-
on-select-all={methods.handleSelectionChange}
-
>
-
{
-
props.showCheckBox && <el-table-column
-
key='showCheckBox'
-
width='55'
-
type='selection'
-
reserve-selection={props.keep}
-
class-name={props.turnRadio ? 'checkBoxRadio' : ''}
-
align='center'
-
/>
-
}
-
{
-
props.showExpand && <el-table-column
-
key='showExpand'
-
type='expand'
-
scopedSlots={{
-
default: scope => {
-
return <fragment row={scope.row}>
-
{
-
slots.expand?.()
-
}
-
</fragment>
-
}
-
}}
-
>
-
</el-table-column>
-
}
-
{
-
props.showIndex && <el-table-column
-
align='center'
-
label='序号'
-
width='50'
-
scopedSlots={{
-
default: scope => {
-
return scope.$index 1
-
}
-
}}
-
>
-
</el-table-column>
-
}
-
{
-
props.tableLabel.map((item: TableLabel) => {
-
return <el-table-column
-
key={item[props.keyId]}
-
width={item.width ?? ''}
-
align={item.align ?? 'center'}
-
label={item.label}
-
show-overflow-tooltip={props.overflowText}
-
fixed={item.fixed}
-
prop={item.prop}
-
scopedSlots={{
-
default: (scope) => {
-
if (item.render) {
-
return <div
-
style='cursor: pointer'
-
onClick={() => item.methods && methods.handleClickon(item.methods, scope.row)}
-
domPropsInnerHTML={item.render(scope.row)}
-
>
-
</div>
-
} else {
-
return <div
-
class='text-no-wrap'
-
onClick={() => item.methods && methods.handleClickon(item.methods, scope.row)}>
-
{
-
Object.prototype.toString.call(item.prop) === '[object Array]' ? methods.propFilter(item.prop, scope.row) : (scope.row[item.prop] ?? '--')
-
}
-
</div>
-
}
-
}
-
}}
-
>
-
</el-table-column>
-
})
-
}
-
{
-
props.option && <el-table-column
-
width={props.option.width}
-
label={props.option.label}
-
fixed={props.option.fixed}
-
align={props.option.align ?? 'center'}
-
scopedSlots={{
-
default: scope => {
-
return props.option.children.length && <div
-
class='flex-box'
-
>
-
{
-
props.option.children.map(item => {
-
return <el-tooltip
-
class='item'
-
effect='light'
-
popper-class='yxp-tooltip-primary'
-
content={item.label}
-
placement='top'
-
>
-
<i
-
class={['yxp-tooltip-icon', item.icon]}
-
plain='true'
-
onClick={() => methods.handleTableButton(scope.row, item.methods)}
-
/>
-
</el-tooltip>
-
})
-
}
-
</div>
-
}
-
}}
-
>
-
</el-table-column>
-
}
-
</el-table>
-
</div>
-
)
-
}
-
})
4、types.ts为类型定义文件
-
/** 表格行数据类型 */
-
export interface TableDataItem {
-
xxx: number;
-
}
-
-
/** 表格基础类型配置 */
-
interface BasicLabel {
-
label: string; // 标题
-
width?: number | string; // 宽度
-
fixed?: string; // 固定位置
-
align?: string; // 行排列
-
visible?: boolean; // 是否展示
-
}
-
-
/** 表格顶部类型配置 */
-
export interface TableLabel extends BasicLabel {
-
prop: string;
-
methods?: string;
-
render?: render;
-
mode?: string;
-
selects?: Select[]
-
}
-
-
/** 表格顶部自定义函数类型 */
-
interface render {
-
(row: TableDataItem): string
-
}
-
-
/** 表格操作栏类型 */
-
export interface OptionLabel extends BasicLabel {
-
prop?: string;
-
children: OptionChild[]
-
}
-
-
/** 表格操作栏子选项类型 */
-
export interface OptionChild {
-
label: string; // 标题
-
icon: string; // icon图标
-
method: string; // 执行方法
-
permission: string | string[]; // 权限
-
}
5、组件调用方式
组件调用:
-
<CommonTable
-
show-index
-
show-check-box={true}
-
loading={loading.value}
-
max-height={550}
-
table-label={tableHeaderData}
-
data={tableData.value}
-
option={tableOptionsData}
-
on-operation={methods.operationHandler}
-
on-handle-selection-change={methods.handleSelectionChange}
-
/>
属性及方法使用说明:
-
/** 表格头部配置 */
-
const tableHeaderData = [
-
{
-
label: '文件大小',
-
prop: 'size',
-
width: '100',
-
render(row) {
-
return xxx
-
}
-
}
-
]
-
-
/** 表格操作栏配置 */
-
const tableOptionsData = {
-
label: '操作',
-
width: '150',
-
fixed: 'right',
-
children: [
-
{
-
label: '操作记录',
-
icon: 'xxx',
-
methods: 'record',
-
permission: ''
-
}
-
]
-
}
-
-
const methods = {
-
/**
-
* 操作栏分发逻辑
-
* @param row 当行数据
-
* @param type 分发函数名
-
*/
-
operationHandler(row: TableDataItem, type: string) {
-
if (type === 'record') { // 操作记录
-
}
-
},
-
/**
-
* 复选框处理回调
-
* @param val 复选框选中的数据
-
*/
-
handleSelectionChange(val: TableDataItem[]) {
-
multipleSelection.value = val
-
}
-
}
有不懂的可以底下评论噢~
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfhjgg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01