1503 lines
41 KiB
Vue
1503 lines
41 KiB
Vue
![]() |
<template>
|
|||
|
<view class="z-table">
|
|||
|
<view class="z-table-main" :style="[{ 'background-color': this.tempbackgroundColor }, { color: this.temptextColor }, { height: tableHeight + 'px' }]">
|
|||
|
<view v-if="!tableLoaded && (!tableData || !columns)" :class="['z-loading', { ztableLoading: tableShow }]"><view class="z-loading-animate"></view></view>
|
|||
|
<!-- 查询过滤器 -->
|
|||
|
<view v-if="tbName.length > 0 || searchBox" class="pagination" :style="[{ 'border-bottom': '1rpx solid ' + templineColor }]">
|
|||
|
<uni-lr-row :layout="searchBoxTW" style="height: 100%;width: 100%;padding:0">
|
|||
|
<uni-input-row
|
|||
|
slot="left"
|
|||
|
v-if="tbName.length > 0 || searchBox"
|
|||
|
type="hint"
|
|||
|
:inputBorder="false"
|
|||
|
v-model="tbName"
|
|||
|
style="height: 100%;"
|
|||
|
:after="false"
|
|||
|
:hintIcons="false"
|
|||
|
inputIcon="info"
|
|||
|
:placeholderColor="temptitleColor"
|
|||
|
:alignment="titleAlignment"
|
|||
|
:iconColor="tempiconColor"
|
|||
|
:readonlyColor="tempbackgroundColor"
|
|||
|
:showButton="searchBox"
|
|||
|
buttonIcon="search"
|
|||
|
@buttonClick="buttonClick"
|
|||
|
></uni-input-row>
|
|||
|
<uni-lr-row v-if="searchBox" slot="right" :layout="40" style="height: 100%;width: 100%;">
|
|||
|
<uni-input-row
|
|||
|
slot="left"
|
|||
|
type="combox"
|
|||
|
rowHeight="100%"
|
|||
|
:after="false"
|
|||
|
:inputBorder="false"
|
|||
|
:textColor="temptextColor"
|
|||
|
:iconColor="tempiconColor"
|
|||
|
:defaultColor="tempbackgroundColor"
|
|||
|
:selectorColor="tempbackgroundColor"
|
|||
|
:verify="true"
|
|||
|
:clearable="true"
|
|||
|
v-model="searchCol"
|
|||
|
:range="searchColData"
|
|||
|
rangeKey="field"
|
|||
|
rangeVal="title"
|
|||
|
placeholder="列名"
|
|||
|
></uni-input-row>
|
|||
|
<uni-input-row
|
|||
|
slot="right"
|
|||
|
type="text"
|
|||
|
rowHeight="100%"
|
|||
|
:after="false"
|
|||
|
:inputBorder="false"
|
|||
|
:textColor="temptextColor"
|
|||
|
:iconColor="tempiconColor"
|
|||
|
:defaultColor="tempbackgroundColor"
|
|||
|
:buttonColor="tempbuttonColor"
|
|||
|
clearable
|
|||
|
showButton
|
|||
|
btConfirm
|
|||
|
buttonIcon="search"
|
|||
|
v-model="searchVal"
|
|||
|
@clear="onSearchClear"
|
|||
|
@confirm="onSearch($event)"
|
|||
|
placeholder="搜索内容"
|
|||
|
></uni-input-row>
|
|||
|
</uni-lr-row>
|
|||
|
</uni-lr-row>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 表格内容 -->
|
|||
|
<!-- "{ height: (searchBox || tbName.length > 0 ? 0 : 10) + (pagination ? 0 : 10) + 80 + '%' }" -->
|
|||
|
<scroll-view scroll-y="true" scroll-x="true" :style="tbHeight">
|
|||
|
<view class="z-table-pack" :style="[{ 'background-color': tempbackgroundColor }, { color: temptextColor }]">
|
|||
|
<!-- 行头部 -->
|
|||
|
<view class="z-table-title" :style="[{ 'border-right': '1rpx solid ' + templineColor }, { 'border-bottom': '1rpx solid ' + templineColor }]">
|
|||
|
<!-- 添加行编号 -->
|
|||
|
<view
|
|||
|
v-if="rowNumbers"
|
|||
|
:class="['z-table-title-item', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + (showSelect ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-top': '1rpx solid ' + templineColor },
|
|||
|
{ width: rowNW + 'rpx' },
|
|||
|
{ 'background-color': tempbackgroundColor },
|
|||
|
{ color: temptextColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view class="z-table-col-text text-center">
|
|||
|
<view v-if="rowCount">{{ tableData.length }}</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<!-- 单选图片显示 -->
|
|||
|
<view
|
|||
|
v-if="showSelect && singleSelect"
|
|||
|
:class="['z-table-title-item', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-top': '1rpx solid ' + templineColor },
|
|||
|
{ left: rowNumbers ? rowNW + 'rpx' : '0' },
|
|||
|
{ width: showSW + 'rpx' },
|
|||
|
{ 'background-color': tempbackgroundColor },
|
|||
|
{ color: temptextColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<uni-icons :color="tempiconColor" type="circle-filled" size="18"></uni-icons>
|
|||
|
</view>
|
|||
|
<!-- 多选复选框显示 -->
|
|||
|
<view
|
|||
|
v-if="showSelect && !singleSelect"
|
|||
|
:class="['z-table-title-item', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-top': '1rpx solid ' + templineColor },
|
|||
|
{ left: rowNumbers ? rowNW + 'rpx' : '0' },
|
|||
|
{ width: showSW + 'rpx' },
|
|||
|
{ 'background-color': tempbackgroundColor },
|
|||
|
{ color: temptextColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view class="select-box" @click="doSelect(true)"><view :class="['select-tip', { selected: selectAll }]"></view></view>
|
|||
|
</view>
|
|||
|
<!-- 列集合遍历 -->
|
|||
|
<view
|
|||
|
class="z-table-title-item"
|
|||
|
:class="{ 'z-table-stick-side': stickSide && index == 0 }"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + (index === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-top': '1rpx solid ' + templineColor },
|
|||
|
{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
|
|||
|
{ width: item.width ? item.width + 'rpx' : '200rpx' },
|
|||
|
{ 'background-color': tempbackgroundColor },
|
|||
|
{ color: temptextColor }
|
|||
|
]"
|
|||
|
v-for="(item, index) in columns"
|
|||
|
:key="index"
|
|||
|
v-if="!item.hidden"
|
|||
|
@click="sort(item.field, index)"
|
|||
|
>
|
|||
|
<view v-if="item.group" style="height: 100%;width: 100%;">
|
|||
|
<!-- 显示列分组标题明细 -->
|
|||
|
<view v-for="(gCol, gIndex) in item.columns" :key="gIndex">
|
|||
|
<view
|
|||
|
v-if="gIndex === 0 && item.gTitle && item.gTitle.length > 0"
|
|||
|
:class="[
|
|||
|
'z-table-col-text',
|
|||
|
{
|
|||
|
'text-left': item.talign === 'left' || talign === 'left',
|
|||
|
'text-center': item.talign === 'center' || talign === 'center',
|
|||
|
'text-right': item.talign === 'right' || talign === 'right'
|
|||
|
}
|
|||
|
]"
|
|||
|
>
|
|||
|
<view v-html="getTitleText(item)"></view>
|
|||
|
</view>
|
|||
|
<view
|
|||
|
v-if="gCol.title && gCol.title.length > 0"
|
|||
|
:class="[
|
|||
|
'z-table-col-text',
|
|||
|
{
|
|||
|
'text-left': gCol.talign === 'left' || talign === 'left',
|
|||
|
'text-center': gCol.talign === 'center' || talign === 'center',
|
|||
|
'text-right': gCol.talign === 'right' || talign === 'right'
|
|||
|
}
|
|||
|
]"
|
|||
|
>
|
|||
|
<view v-html="getTitleText(gCol)"></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view
|
|||
|
v-else
|
|||
|
:class="[
|
|||
|
'z-table-col-text',
|
|||
|
{
|
|||
|
'text-left': item.talign === 'left' || talign === 'left',
|
|||
|
'text-center': item.talign === 'center' || talign === 'center',
|
|||
|
'text-right': item.talign === 'right' || talign === 'right'
|
|||
|
}
|
|||
|
]"
|
|||
|
>
|
|||
|
<view v-if="item.title && item.title.length > 0" v-html="getTitleText(item)"></view>
|
|||
|
<view v-if="item.hasOwnProperty('field') && item.hasOwnProperty('sort') && tableData.length" class="sort">
|
|||
|
<view
|
|||
|
class="up-arrow"
|
|||
|
:style="{ 'border-bottom': '4px solid ' + (nowSortKey == item.field && sortType == 'asc' ? temptitleColor : temptextColor) }"
|
|||
|
></view>
|
|||
|
<view
|
|||
|
class="down-arrow"
|
|||
|
:style="{ 'border-top': '4px solid ' + (nowSortKey == item.field && sortType == 'desc' ? temptitleColor : temptextColor) }"
|
|||
|
></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 行内容 -->
|
|||
|
<view
|
|||
|
v-if="tableData.length"
|
|||
|
:style="[{ 'border-right': '1rpx solid ' + templineColor }]"
|
|||
|
:class="['table-container-box', { 'short-table': !longTable && showBottomSum }]"
|
|||
|
>
|
|||
|
<view
|
|||
|
v-if="row.rowSearch && (!pagination || (current * pageSize - pageSize <= iIndex && iIndex < current * pageSize))"
|
|||
|
class="z-table-container-row"
|
|||
|
:class="{ 'z-table-has-bottom': showBottomSum }"
|
|||
|
v-for="(row, iIndex) in tableData"
|
|||
|
:key="iIndex"
|
|||
|
:style="onRowStyle(row, iIndex)"
|
|||
|
>
|
|||
|
<!-- 添加行编号 -->
|
|||
|
<view
|
|||
|
v-if="rowNumbers"
|
|||
|
:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + (showSelect ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-top': '1rpx solid ' + (iIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-bottom': (!fillRow && iIndex == tableData.length - 1 ? '1' : '0') + 'rpx solid ' + templineColor },
|
|||
|
{ width: rowNW + 'rpx' },
|
|||
|
{ 'background-color': tempbackgroundColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view class="z-table-col-text text-center">
|
|||
|
<view>{{ iIndex + 1 }}</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<!-- 添加复选框 -->
|
|||
|
<view
|
|||
|
v-if="showSelect"
|
|||
|
:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-top': '1rpx solid ' + (iIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-bottom': (!fillRow && iIndex == tableData.length - 1 ? '1' : '0') + 'rpx solid ' + templineColor },
|
|||
|
{ left: rowNumbers ? rowNW + 'rpx' : '0' },
|
|||
|
{ width: showSW + 'rpx' },
|
|||
|
{ 'background-color': tempbackgroundColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view class="select-box" @click="doSelect(false, iIndex, row)"><view :class="['select-tip', { selected: row['rowChecked'] }]"></view></view>
|
|||
|
</view>
|
|||
|
<!-- 行数据遍历 -->
|
|||
|
<view
|
|||
|
:class="['z-table-container-col', { 'z-table-stick-side': stickSide && jIndex == 0 }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + (jIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-top': '1rpx solid ' + (iIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-bottom': (!fillRow && iIndex == tableData.length - 1 ? '1' : '0') + 'rpx solid ' + templineColor },
|
|||
|
{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
|
|||
|
{ width: col.width ? col.width + 'rpx' : '200rpx' }
|
|||
|
]"
|
|||
|
v-for="(col, jIndex) in columns"
|
|||
|
:key="jIndex"
|
|||
|
v-if="!col.hidden"
|
|||
|
@click="itemClick(iIndex, row, col)"
|
|||
|
>
|
|||
|
<!-- 多分组的时候,是否需要把内容填充 style="height: 100%;width: 100%;" -->
|
|||
|
<view v-if="col.group">
|
|||
|
<view v-for="(gCol, gIndex) in col['columns']" :key="gIndex">
|
|||
|
<view
|
|||
|
v-html="getRowContent(row, gCol, iIndex)"
|
|||
|
:class="[
|
|||
|
'z-table-col-text',
|
|||
|
{
|
|||
|
'text-left': col.align === 'left' || align === 'left',
|
|||
|
'text-center': col.align === 'center' || align === 'center',
|
|||
|
'text-right': col.align === 'right' || align === 'right'
|
|||
|
}
|
|||
|
]"
|
|||
|
></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view
|
|||
|
v-else
|
|||
|
v-html="getRowContent(row, col, iIndex)"
|
|||
|
:class="[
|
|||
|
'z-table-col-text',
|
|||
|
{
|
|||
|
'text-left': col.align === 'left' || align === 'left',
|
|||
|
'text-center': col.align === 'center' || align === 'center',
|
|||
|
'text-right': col.align === 'right' || align === 'right'
|
|||
|
}
|
|||
|
]"
|
|||
|
></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 空白行 -->
|
|||
|
<view
|
|||
|
v-if="fillRow && tableData.length < fillCount"
|
|||
|
class="z-table-container-row"
|
|||
|
:class="{ 'z-table-has-bottom': showBottomSum }"
|
|||
|
v-for="(row, marginIndex) in fillCount"
|
|||
|
>
|
|||
|
<!-- 添加行编号 -->
|
|||
|
<view
|
|||
|
v-if="rowNumbers"
|
|||
|
:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + (showSelect ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ width: rowNW + 'rpx' },
|
|||
|
{ 'background-color': (tableData.length + marginIndex) % 2 === 0 ? tempbackgroundColor2 : tempbackgroundColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view class="z-table-col-text text-center"><view></view></view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 添加复选框 -->
|
|||
|
<view
|
|||
|
v-if="showSelect"
|
|||
|
:class="['z-table-container-col', { 'z-table-stick-side': fixedSelectBox }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + templineColor },
|
|||
|
{ left: rowNumbers ? rowNW + 'rpx' : '0' },
|
|||
|
{ width: showSW + 'rpx' },
|
|||
|
{ 'background-color': (tableData.length + marginIndex) % 2 === 0 ? tempbackgroundColor2 : tempbackgroundColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view><view class="select-tip"></view></view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 行数据遍历 -->
|
|||
|
<view
|
|||
|
:class="['z-table-container-col', { 'z-table-stick-side': stickSide && jIndex == 0 }]"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + (marginjIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
|
|||
|
{ width: col.width ? col.width + 'rpx' : '200rpx' },
|
|||
|
{ 'background-color': (tableData.length + marginIndex) % 2 === 0 ? tempbackgroundColor2 : tempbackgroundColor }
|
|||
|
]"
|
|||
|
v-for="(col, marginjIndex) in columns"
|
|||
|
v-if="!col.hidden"
|
|||
|
>
|
|||
|
<view class="z-table-col-text"></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
|
|||
|
<!-- 页脚 -->
|
|||
|
<view
|
|||
|
:class="['z-table-bottom', { 'long-table': longTable }]"
|
|||
|
:style="[{ 'border-right': '1rpx solid ' + templineColor }, { 'border-bottom': '1rpx solid ' + templineColor }]"
|
|||
|
v-if="showBottomSum && tableData.length"
|
|||
|
>
|
|||
|
<!-- 行号和复选框站的宽度 -->
|
|||
|
<view
|
|||
|
class="z-table-bottom-col z-table-stick-side"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-right': '1rpx solid ' + templineColor },
|
|||
|
{ 'border-top': '1rpx solid ' + templineColor },
|
|||
|
{ width: (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + (rowNumbers && showSelect ? -1 : 0) + 'rpx' },
|
|||
|
{ 'background-color': tempfooterColor },
|
|||
|
{ color: temptextColor }
|
|||
|
]"
|
|||
|
>
|
|||
|
<view class="z-table-bottom-text"><uni-icons :color="tempiconColor" type="huizong" size="20" /></view>
|
|||
|
</view>
|
|||
|
<!-- 遍历列数,分别计算合计值 -->
|
|||
|
<view
|
|||
|
class="z-table-bottom-col"
|
|||
|
:class="{ 'z-table-stick-side': stickSide && sumIndex == 0 }"
|
|||
|
:style="[
|
|||
|
{ 'border-left': '1rpx solid ' + (sumIndex === 0 ? 'rgb(0, 0, 0, 0)' : templineColor) },
|
|||
|
{ 'border-top': '1rpx solid ' + templineColor },
|
|||
|
{ left: stickSide ? (rowNumbers ? rowNW : 0) + (showSelect ? showSW : 0) + 'rpx' : '0' },
|
|||
|
{ width: sumCol.width ? sumCol.width + 'rpx' : '200rpx' },
|
|||
|
{ 'background-color': tempfooterColor },
|
|||
|
{ color: temptextColor }
|
|||
|
]"
|
|||
|
v-for="(sumCol, sumIndex) in columns"
|
|||
|
:key="sumIndex"
|
|||
|
v-if="!sumCol['hidden']"
|
|||
|
>
|
|||
|
<view
|
|||
|
class="z-table-bottom-text"
|
|||
|
:class="[
|
|||
|
'z-table-col-text',
|
|||
|
{
|
|||
|
'text-left': sumCol.align === 'left' || align === 'left',
|
|||
|
'text-center': sumCol.align === 'center' || align === 'center',
|
|||
|
'text-right': sumCol.align === 'right' || align === 'right'
|
|||
|
}
|
|||
|
]"
|
|||
|
>
|
|||
|
<!-- 默认总计,后面扩展平均值、最大最小值都可以 -->
|
|||
|
<text>{{ dosum(sumCol) }}</text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</scroll-view>
|
|||
|
|
|||
|
<!-- 分页器 -->
|
|||
|
<view v-if="pagination" class="pagination" :style="[{ 'border-top': '1rpx solid ' + templineColor }]">
|
|||
|
<uni-pagination
|
|||
|
style="height: 100%;"
|
|||
|
show-icon="true"
|
|||
|
:pageSize="pageSize"
|
|||
|
:iconColor="tempiconColor"
|
|||
|
:textColor1="temptitleColor"
|
|||
|
:textColor="temptextColor"
|
|||
|
:buttonColor="tempbuttonColor"
|
|||
|
:total="searchLen > 0 ? searchLen : tableData.length"
|
|||
|
:current="current"
|
|||
|
@change="paginationChange"
|
|||
|
></uni-pagination>
|
|||
|
</view>
|
|||
|
|
|||
|
<view v-if="tableData && tableData.length == 0 && !tableLoaded" class="table-empty">
|
|||
|
<!-- image v-if="!showLoading" class="empty-img" src="../static/empty.png"></image -->
|
|||
|
<view v-html="showLoading ? '' : emptyText"></view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
/*
|
|||
|
* 表格使用
|
|||
|
* 注意如果需要异步加载,需要把tableData初始值设为false,当没有数据的时候值为空数组
|
|||
|
* props: tableData [Array | Boolean] | 表格数据 如果为false则显示loading
|
|||
|
* columns [Array | Boolean] | 数据映射表 如果为false则显示loading 每列params => title(表头文字可以是html字符串模版), width(每列宽度) [, key(对应tableData的字段名) || format(自定义内容), sort(是否要排序), isLink(是否显示为超链接Object)]
|
|||
|
* format格式: {template: 字符串模版用#key#表示需要被替换的数据,names: 对应template属性内要被替换的内容的key}
|
|||
|
* isLink格式: {url: 链接地址, params: 地址带的参数Array[key|value, key|value, ...]每一项都是key和value以'|'链接,如果不带'|'默认键值同名
|
|||
|
* cellClick(是否监听点击事件Boolean)}
|
|||
|
* stickSide Boolean | 是否固定右侧首栏 默认不显示
|
|||
|
* showBottomSum Boolean | 是否显示底部统计 默认不显示
|
|||
|
* showLoading Boolean | 是否首次加载首次加载不显示暂无数据内容
|
|||
|
* emptyText String | 空数据显示的文字内容
|
|||
|
* tableHeight Number | 设置表格高度会滚动
|
|||
|
* sort Boolean | 开启排序
|
|||
|
* showSelect Boolean | 开启选择
|
|||
|
* singleSelect Boolean | 在开启选择的状态下是否开起单选
|
|||
|
* align String | 内容对齐方式 left center right
|
|||
|
* talign String | 表头对齐方式 left center right
|
|||
|
*
|
|||
|
* event: onSort | 排序事件 返回{field: 被排序列的字段名, type: 正序'asc'/倒序'desc'}
|
|||
|
* onSelect | 选中时触发 返回选择的行的下标
|
|||
|
* onClick | 单元格点击事件 返回点击单元格所属行的数据
|
|||
|
*
|
|||
|
* function: resetSort | 调用后重置排序 *注意:不会触发sort事件
|
|||
|
*
|
|||
|
* */
|
|||
|
export default {
|
|||
|
data() {
|
|||
|
return {
|
|||
|
version: '1.1.3',
|
|||
|
nowSortKey: '',
|
|||
|
sortType: 'desc', // asc/desc 升序/降序
|
|||
|
longTable: true,
|
|||
|
lineHeight: uni.upx2px(64),
|
|||
|
tableLoaded: false,
|
|||
|
tableShow: true,
|
|||
|
selectAll: false,
|
|||
|
selectArr: [],
|
|||
|
//分页器,每页数据量
|
|||
|
pageSize: 100,
|
|||
|
//分页器,当前页
|
|||
|
current: 1,
|
|||
|
//查询过滤后的数据源总数
|
|||
|
searchLen: 0,
|
|||
|
//查询列下拉框数据源
|
|||
|
searchColData: [],
|
|||
|
//查询列下拉框选中行数据
|
|||
|
searchCol: {},
|
|||
|
//查询过滤输入框输入的内容
|
|||
|
searchVal: '',
|
|||
|
//查询管理器中的宽度比例 title width
|
|||
|
searchBoxTW: 100,
|
|||
|
//按钮颜色
|
|||
|
tempbuttonColor: '#ffffff',
|
|||
|
//选择行背景颜色
|
|||
|
tempselectRowColor: '#ffe48d',
|
|||
|
//图片按钮颜色
|
|||
|
tempiconColor: '#000000',
|
|||
|
//标题类字体颜色
|
|||
|
temptitleColor: '#5500ff',
|
|||
|
//文本颜色/线颜色
|
|||
|
temptextColor: '#000000',
|
|||
|
//线颜色
|
|||
|
templineColor: '#d4d4d4',
|
|||
|
//主背景颜色
|
|||
|
tempbackgroundColor: '#f3f3f3',
|
|||
|
//次背景颜色
|
|||
|
tempbackgroundColor2: '#ffffff',
|
|||
|
//页脚背景颜色
|
|||
|
tempfooterColor: '#d4e6ff',
|
|||
|
fillCount: 15
|
|||
|
};
|
|||
|
},
|
|||
|
computed: {
|
|||
|
//表格高度样式设置,计算是否显示表头和分页器,然后计算出行内容高度
|
|||
|
tbHeight() {
|
|||
|
let h=0;
|
|||
|
if(this.searchBox || this.tbName.length > 0){
|
|||
|
h+=33;
|
|||
|
}
|
|||
|
if(this.pagination)
|
|||
|
{
|
|||
|
h+=33;
|
|||
|
}
|
|||
|
return {height:this.tableHeight-h+"px"};
|
|||
|
}
|
|||
|
},
|
|||
|
props: {
|
|||
|
tbName: {
|
|||
|
type: String,
|
|||
|
default: ''
|
|||
|
},
|
|||
|
tableData: {
|
|||
|
type: [Array, Boolean],
|
|||
|
default() {
|
|||
|
return false;
|
|||
|
}
|
|||
|
},
|
|||
|
columns: {
|
|||
|
/*
|
|||
|
*
|
|||
|
* [{title: xxx, field: 当前列展示对象名, width: 列宽, render: function}]
|
|||
|
*
|
|||
|
* */
|
|||
|
type: [Array, Boolean],
|
|||
|
required: true
|
|||
|
},
|
|||
|
//是否固定右侧首栏 默认不显示
|
|||
|
stickSide: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
//是否显示底部统计 默认不显示
|
|||
|
showBottomSum: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
//是否首次加载首次加载不显示暂无数据内容
|
|||
|
showLoading: {
|
|||
|
type: Boolean,
|
|||
|
default: true
|
|||
|
},
|
|||
|
//空数据显示的文字内容
|
|||
|
emptyText: {
|
|||
|
type: String,
|
|||
|
default: '暂无数据'
|
|||
|
},
|
|||
|
//设置表格高度会滚动
|
|||
|
tableHeight: {
|
|||
|
type: [Number, Boolean],
|
|||
|
default: 500
|
|||
|
},
|
|||
|
//开启选择
|
|||
|
showSelect: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
//在开启选择的状态下是否开起单选
|
|||
|
singleSelect: {
|
|||
|
type: Boolean,
|
|||
|
default: true
|
|||
|
},
|
|||
|
//内容对齐方式 left center right
|
|||
|
align: {
|
|||
|
type: String,
|
|||
|
default: 'left' // right|center|left
|
|||
|
},
|
|||
|
//表头对齐方式 left center right
|
|||
|
talign: {
|
|||
|
type: String,
|
|||
|
default: 'left' // right|center|left
|
|||
|
},
|
|||
|
//如果为true,当用户点击行的时候该复选框就会被选中或取消选中。
|
|||
|
//如果为false,当用户仅在点击该复选框的时候才会被选中或取消。
|
|||
|
checkOnSelect: {
|
|||
|
type: Boolean,
|
|||
|
default: true
|
|||
|
},
|
|||
|
//是否固定复选框
|
|||
|
fixedSelectBox: {
|
|||
|
type: Boolean,
|
|||
|
default: true
|
|||
|
},
|
|||
|
//是否显示总行数。
|
|||
|
rowCount: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
//如果为true,则显示一个行号列。
|
|||
|
rowNumbers: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
//表格数据查询操作
|
|||
|
searchBox: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
|
|||
|
//表格数据分页操作
|
|||
|
pagination: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
//行序号宽度 rowNumbersWidth
|
|||
|
rowNW: {
|
|||
|
type: Number,
|
|||
|
default: 50
|
|||
|
},
|
|||
|
//复选框宽度 showSelectWidth
|
|||
|
showSW: {
|
|||
|
type: Number,
|
|||
|
default: 50
|
|||
|
},
|
|||
|
// 主题颜色,默认白色
|
|||
|
theme: {
|
|||
|
type: String,
|
|||
|
default: ''
|
|||
|
},
|
|||
|
//按钮背景颜色
|
|||
|
buttonColor: {
|
|||
|
type: String,
|
|||
|
default: '#ffffff'
|
|||
|
},
|
|||
|
//选择行背景颜色
|
|||
|
selectRowColor: {
|
|||
|
type: String,
|
|||
|
default: '#ffe48d'
|
|||
|
},
|
|||
|
//图片按钮颜色
|
|||
|
iconColor: {
|
|||
|
type: String,
|
|||
|
default: '#000000'
|
|||
|
},
|
|||
|
//标题类字体颜色
|
|||
|
titleColor: {
|
|||
|
type: String,
|
|||
|
default: '#5500ff'
|
|||
|
},
|
|||
|
//标题类字体对齐方式 默认左对齐
|
|||
|
titleAlignment: {
|
|||
|
type: String,
|
|||
|
default: 'left'
|
|||
|
},
|
|||
|
//文本颜色
|
|||
|
textColor: {
|
|||
|
type: String,
|
|||
|
default: '#000000'
|
|||
|
},
|
|||
|
//线条颜色
|
|||
|
lineColor: {
|
|||
|
type: String,
|
|||
|
default: '#d4d4d4'
|
|||
|
},
|
|||
|
//主背景颜色
|
|||
|
backgroundColor: {
|
|||
|
type: String,
|
|||
|
default: '#f3f3f3'
|
|||
|
},
|
|||
|
//次背景颜色
|
|||
|
backgroundColor2: {
|
|||
|
type: String,
|
|||
|
default: '#ffffff'
|
|||
|
},
|
|||
|
//页脚颜色
|
|||
|
footerColor: {
|
|||
|
type: String,
|
|||
|
default: '#d4e6ff'
|
|||
|
},
|
|||
|
//是否填充空行
|
|||
|
fillRow: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
created() {},
|
|||
|
mounted() {
|
|||
|
//初始化表格数据
|
|||
|
this.init();
|
|||
|
|
|||
|
//设置主题颜色
|
|||
|
if (this.theme === 'white') {
|
|||
|
//白色
|
|||
|
//按钮颜色
|
|||
|
this.tempbuttonColor = '#ffffff';
|
|||
|
//选择行背景颜色
|
|||
|
this.tempselectRowColor = '#ffe48d';
|
|||
|
//图片按钮颜色
|
|||
|
this.tempiconColor = '#000000';
|
|||
|
//标题类字体颜色
|
|||
|
this.temptitleColor = '#5500ff';
|
|||
|
//文本颜色/线颜色
|
|||
|
this.temptextColor = '#000000';
|
|||
|
//线颜色
|
|||
|
this.templineColor = '#d4d4d4';
|
|||
|
//主背景颜色
|
|||
|
this.tempbackgroundColor = '#f3f3f3';
|
|||
|
//次背景颜色
|
|||
|
this.tempbackgroundColor2 = '#ffffff';
|
|||
|
//页脚颜色
|
|||
|
this.tempfooterColor = '#d4e6ff';
|
|||
|
} else if (this.theme === 'black') {
|
|||
|
//黑色
|
|||
|
this.tempbuttonColor = '#5e6576';
|
|||
|
this.tempselectRowColor = '#5e6434';
|
|||
|
this.tempiconColor = '#bcc1d6';
|
|||
|
this.temptitleColor = '#2488ea';
|
|||
|
this.temptextColor = '#bcc1d6';
|
|||
|
this.templineColor = '#8e93a1';
|
|||
|
this.tempbackgroundColor = '#0f1628';
|
|||
|
this.tempbackgroundColor2 = '#1c263f';
|
|||
|
this.tempfooterColor = '#545834';
|
|||
|
} else {
|
|||
|
//自定义
|
|||
|
this.tempbuttonColor = this.buttonColor;
|
|||
|
this.tempselectRowColor = this.selectRowColor;
|
|||
|
this.tempiconColor = this.iconColor;
|
|||
|
this.temptitleColor = this.titleColor;
|
|||
|
this.temptextColor = this.textColor;
|
|||
|
this.templineColor = this.lineColor;
|
|||
|
this.tempbackgroundColor = this.backgroundColor;
|
|||
|
this.tempbackgroundColor2 = this.backgroundColor2;
|
|||
|
this.tempfooterColor = this.footerColor;
|
|||
|
}
|
|||
|
},
|
|||
|
watch: {
|
|||
|
columns(e) {
|
|||
|
this.init();
|
|||
|
},
|
|||
|
tableData() {
|
|||
|
this.init();
|
|||
|
},
|
|||
|
buttonColor(newVal, oldVal) {
|
|||
|
this.tempbuttonColor = newVal;
|
|||
|
},
|
|||
|
selectRowColor(newVal, oldVal) {
|
|||
|
this.tempselectRowColor = newVal;
|
|||
|
},
|
|||
|
iconColor(newVal, oldVal) {
|
|||
|
this.tempiconColor = newVal;
|
|||
|
},
|
|||
|
titleColor(newVal, oldVal) {
|
|||
|
this.temptitleColor = newVal;
|
|||
|
},
|
|||
|
textColor(newVal, oldVal) {
|
|||
|
this.temptextColor = newVal;
|
|||
|
},
|
|||
|
backgroundColor(newVal, oldVal) {
|
|||
|
this.tempbackgroundColor = newVal;
|
|||
|
},
|
|||
|
backgroundColor2(newVal, oldVal) {
|
|||
|
this.tempbackgroundColor2 = newVal;
|
|||
|
}
|
|||
|
// tableHeight(newVal,oldVal){
|
|||
|
// console.log(newVal+'高度改变'+oldVal);
|
|||
|
// if (newVal != oldVal) {
|
|||
|
// console.log('高度改变');
|
|||
|
// }
|
|||
|
// },
|
|||
|
},
|
|||
|
|
|||
|
methods: {
|
|||
|
//行样式操作
|
|||
|
onRowStyle(row, index) {
|
|||
|
let backgroundColor = row['rowChecked'] ? this.tempselectRowColor : index % 2 === 0 ? this.tempbackgroundColor2 : this.tempbackgroundColor;
|
|||
|
let css = {
|
|||
|
'background-color': backgroundColor,
|
|||
|
color: this.temptextColor
|
|||
|
};
|
|||
|
this.$emit('onRowStyle', { index: index, row: row }, res => {
|
|||
|
var assignObj = Object.assign(css, res);
|
|||
|
});
|
|||
|
return css;
|
|||
|
},
|
|||
|
|
|||
|
async init() {
|
|||
|
// 重置选择内容
|
|||
|
this.selectAll = false;
|
|||
|
this.selectArr = [];
|
|||
|
this.tableLoaded = false;
|
|||
|
this.tableShow = true;
|
|||
|
this.searchLen = 0;
|
|||
|
this.pageSize = 100;
|
|||
|
let _this = this;
|
|||
|
let container = await _this.getPageSize('.z-table-container'),
|
|||
|
pack = await _this.getPageSize('.z-table-pack');
|
|||
|
_this.timer && clearTimeout(_this.timer);
|
|||
|
if (container && pack) {
|
|||
|
_this.$nextTick(function() {
|
|||
|
if (_this.tableData && _this.tableData.length) {
|
|||
|
_this.tableShow = false;
|
|||
|
_this.timer = setTimeout(function() {
|
|||
|
_this.tableLoaded = true;
|
|||
|
}, 300);
|
|||
|
}
|
|||
|
});
|
|||
|
if (container.height != pack.height) {
|
|||
|
_this.longTable = true;
|
|||
|
} else {
|
|||
|
_this.longTable = false;
|
|||
|
}
|
|||
|
} else {
|
|||
|
_this.tableLoaded = false;
|
|||
|
_this.$nextTick(function() {
|
|||
|
_this.tableShow = true;
|
|||
|
});
|
|||
|
}
|
|||
|
if (_this.tableData && _this.tableData.length) {
|
|||
|
_this.tableData.forEach((item, index) => {
|
|||
|
this.$set(item, 'rowChecked', false);
|
|||
|
this.$set(item, 'rowSearch', true);
|
|||
|
this.$set(item, 'rowIndex', index);
|
|||
|
});
|
|||
|
}
|
|||
|
let tempSearchColData = [];
|
|||
|
if (_this.columns && _this.columns.length) {
|
|||
|
_this.columns.forEach((item, index) => {
|
|||
|
if (item['group'] && item['columns'].length > 0) {
|
|||
|
item['columns'].forEach((gItem, gIndex) => {
|
|||
|
if (gItem.field && gItem.title) {
|
|||
|
this.$set(gItem, 'index', index + gIndex);
|
|||
|
tempSearchColData.push(gItem);
|
|||
|
}
|
|||
|
});
|
|||
|
} else {
|
|||
|
if (item.field && item.title) {
|
|||
|
this.$set(item, 'index', index);
|
|||
|
tempSearchColData.push(item);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
this.searchColData = tempSearchColData;
|
|||
|
}
|
|||
|
},
|
|||
|
getPageSize(selecter) {
|
|||
|
// 获取元素信息
|
|||
|
let query = uni.createSelectorQuery().in(this),
|
|||
|
_this = this;
|
|||
|
return new Promise((resolve, reject) => {
|
|||
|
query
|
|||
|
.select(selecter)
|
|||
|
.boundingClientRect(res => {
|
|||
|
resolve(res);
|
|||
|
})
|
|||
|
.exec();
|
|||
|
});
|
|||
|
},
|
|||
|
//页脚计算数量
|
|||
|
dosum({ field, noSum = false, formatNum = true }) {
|
|||
|
let sum = '-';
|
|||
|
if (noSum) return sum;
|
|||
|
if (this.tableData) {
|
|||
|
if (
|
|||
|
this.tableData.every(item => {
|
|||
|
return !Number.isNaN(item[field] - 0);
|
|||
|
})
|
|||
|
) {
|
|||
|
sum = 0;
|
|||
|
this.tableData.map((item, index) => {
|
|||
|
if (!field && index != 0) {
|
|||
|
sum = '-';
|
|||
|
} else {
|
|||
|
let val = item[field] - 0;
|
|||
|
if (Number.isNaN(val) || !item['rowSearch']) {
|
|||
|
sum += 0;
|
|||
|
} else {
|
|||
|
sum += val;
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
// sum = sum == 0 ? "-" : sum
|
|||
|
// return formatNum ? this.numTransform(sum) : sum
|
|||
|
return sum;
|
|||
|
},
|
|||
|
//得到单元格html内容
|
|||
|
getRowContent(row, col, index) {
|
|||
|
let tempHTML = '';
|
|||
|
//得到内容
|
|||
|
let rowKey = row[col.field];
|
|||
|
if ([null, ''].includes(rowKey)) {
|
|||
|
rowKey = '-';
|
|||
|
}
|
|||
|
let { formatNum = true } = col;
|
|||
|
|
|||
|
if (rowKey || rowKey === 0) {
|
|||
|
tempHTML = rowKey;
|
|||
|
// tempHTML = isNaN(rowKey - 0) || !formatNum
|
|||
|
// ? rowKey
|
|||
|
// : this.numTransform(rowKey - 0);
|
|||
|
}
|
|||
|
|
|||
|
//设置自定义内容
|
|||
|
if (col.format) {
|
|||
|
tempHTML = col.format(rowKey, row, index);
|
|||
|
}
|
|||
|
|
|||
|
tempHTML = "<view style='white-space:normal;word-break:break-all;word-wrap:break-word;'>" + tempHTML + '</view>';
|
|||
|
|
|||
|
//设置超链接路径
|
|||
|
if (col.link) {
|
|||
|
let link = col.link(tempHTML, row, index);
|
|||
|
let urlParam = {};
|
|||
|
if (link.params && link.params.length > 0) {
|
|||
|
link.params.forEach(item => {
|
|||
|
if (~item.indexOf('|')) {
|
|||
|
let temp = item.split('|');
|
|||
|
urlParam[temp[0]] = row[temp[1]];
|
|||
|
} else {
|
|||
|
urlParam[item] = row[item];
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
let url = this.setUrlParams(link.url, urlParam); //得到超链接参数
|
|||
|
tempHTML = '<a style="color:' + this.temptitleColor + '" href="' + url + '">' + tempHTML + '</a>';
|
|||
|
}
|
|||
|
|
|||
|
//设置自定义单元格样式
|
|||
|
if (col.styler) {
|
|||
|
let align = 'flex-start'; //默认 left
|
|||
|
if (col.align === 'center' || align === 'center') {
|
|||
|
align = 'center';
|
|||
|
}
|
|||
|
if (col.align === 'right' || align === 'right') {
|
|||
|
align = 'flex-end';
|
|||
|
}
|
|||
|
let style = ' display: flex;' + 'width: 100%;' + 'height: 100%;' + 'flex: 1;' + 'justify-content: ' + align + ';' + 'align-content:center; ';
|
|||
|
style += col.styler(rowKey, row, index);
|
|||
|
tempHTML = '<view style="' + style + '"><view>' + tempHTML + '</view></view>';
|
|||
|
}
|
|||
|
|
|||
|
return tempHTML.toString();
|
|||
|
},
|
|||
|
// 得到超链接参数
|
|||
|
setUrlParams(url, params) {
|
|||
|
let tempUrl = url,
|
|||
|
keyArr = Object.keys(params);
|
|||
|
keyArr.forEach(item => {
|
|||
|
tempUrl += `&${item}=${params[item]}`;
|
|||
|
});
|
|||
|
tempUrl = tempUrl.replace(/\&/, '?');
|
|||
|
return tempUrl;
|
|||
|
},
|
|||
|
//排序操作
|
|||
|
sort(field, index) {
|
|||
|
if (!field || !this.columns[index].sort) {
|
|||
|
return;
|
|||
|
}
|
|||
|
// 排序功能: 如果点击的排序按钮是原先的 那么更改排序类型
|
|||
|
// 如果点击的另一个排序按钮 那么选择当前排序并且排序类型改为降序(desc)
|
|||
|
if (field != this.nowSortKey) {
|
|||
|
this.nowSortKey = field;
|
|||
|
this.sortType = 'desc';
|
|||
|
} else {
|
|||
|
this.toggleSort();
|
|||
|
}
|
|||
|
//优先先本地排序,如果需要重新从数据库查询可调用onSort事件
|
|||
|
let arr = this.tableData;
|
|||
|
for (let j = 0; j < arr.length - 1; j++) {
|
|||
|
//外层循环,控制趟数,每一次找到一个最大值
|
|||
|
for (let i = 0; i < arr.length - 1 - j; i++) {
|
|||
|
// 内层循环,控制比较的次数,并且判断两个数的大小
|
|||
|
if (this.sortType == 'asc') {
|
|||
|
if (arr[i][this.nowSortKey] > arr[i + 1][this.nowSortKey]) {
|
|||
|
let temp = arr[i + 1];
|
|||
|
arr[i + 1] = arr[i];
|
|||
|
arr[i] = temp;
|
|||
|
}
|
|||
|
} else if (arr[i][this.nowSortKey] < arr[i + 1][this.nowSortKey]) {
|
|||
|
let temp = arr[i + 1];
|
|||
|
arr[i + 1] = arr[i];
|
|||
|
arr[i] = temp;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
this.$emit('onSort', {
|
|||
|
field: this.nowSortKey,
|
|||
|
type: this.sortType
|
|||
|
});
|
|||
|
},
|
|||
|
//排序结果
|
|||
|
toggleSort() {
|
|||
|
this.sortType = this.sortType == 'asc' ? 'desc' : 'asc';
|
|||
|
},
|
|||
|
// 页脚汇总
|
|||
|
numTransform(n) {
|
|||
|
if (Number.isNaN(n - 0)) {
|
|||
|
return n;
|
|||
|
}
|
|||
|
if (Math.abs(n) >= 100000000) {
|
|||
|
n = Number((n / 100000000).toFixed(1)) + '亿';
|
|||
|
} else if (Math.abs(n) >= 10000) {
|
|||
|
n = Number((n / 10000).toFixed(1)) + '万';
|
|||
|
}
|
|||
|
return n.toString();
|
|||
|
},
|
|||
|
//重置排序
|
|||
|
resetSort() {
|
|||
|
// 重置排序状态
|
|||
|
this.nowSortKey = '';
|
|||
|
this.sortType = 'desc';
|
|||
|
},
|
|||
|
// 单元格点击事件
|
|||
|
itemClick(index, row, col) {
|
|||
|
//隐藏查询工具栏
|
|||
|
if (this.searchBoxTW === 0) {
|
|||
|
this.buttonClick();
|
|||
|
}
|
|||
|
//点击就选中行
|
|||
|
if (this.checkOnSelect) {
|
|||
|
this.doSelect(false, index, row);
|
|||
|
}
|
|||
|
//监听单元格点击事件
|
|||
|
if (col.cellClick) {
|
|||
|
this.$emit('onClick', { index: index, row: row, col: col });
|
|||
|
}
|
|||
|
},
|
|||
|
//选中行事件 isAll:是否为全选
|
|||
|
doSelect(isAll = false, thisIndex, thisRow) {
|
|||
|
if (isAll) {
|
|||
|
this.selectArr = [];
|
|||
|
this.selectAll = !this.selectAll;
|
|||
|
this.tableData.forEach((item, index) => {
|
|||
|
if (this.selectAll) {
|
|||
|
if (item['rowSearch']) {
|
|||
|
if (!item['rowChecked']) {
|
|||
|
this.$set(item, 'rowChecked', true);
|
|||
|
}
|
|||
|
this.selectArr.push(index);
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (item['rowChecked']) {
|
|||
|
this.$set(item, 'rowChecked', false);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
} else {
|
|||
|
const thisCheck = this.tableData[thisIndex]['rowChecked'] || false;
|
|||
|
this.$set(this.tableData[thisIndex], 'rowChecked', !thisCheck);
|
|||
|
//检查是否已经为全部选中状态
|
|||
|
var tempSelectAll = true;
|
|||
|
//单选
|
|||
|
if (this.singleSelect) {
|
|||
|
//判断是不是原来选择的索引,如果就直接清空,不需要在push到选择数组中
|
|||
|
if (this.selectArr.length > 0 && this.selectArr[0] == thisIndex) {
|
|||
|
this.selectArr = [];
|
|||
|
} else {
|
|||
|
this.selectArr = [];
|
|||
|
this.selectArr.push(thisIndex);
|
|||
|
}
|
|||
|
tempSelectAll = false;
|
|||
|
}
|
|||
|
this.selectArr = [];
|
|||
|
for (let i = 0; i < this.tableData.length; i++) {
|
|||
|
if (this.singleSelect && thisIndex !== i) {
|
|||
|
//单选
|
|||
|
//除了当前选中的,其他全部为未选中状态
|
|||
|
this.$set(this.tableData[i], 'rowChecked', false);
|
|||
|
} else {
|
|||
|
//多选
|
|||
|
if (tempSelectAll && !this.tableData[i]['rowChecked']) {
|
|||
|
tempSelectAll = false;
|
|||
|
}
|
|||
|
if (this.tableData[i]['rowChecked']) {
|
|||
|
this.selectArr.push(i);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
this.selectAll = tempSelectAll;
|
|||
|
}
|
|||
|
const index = this.singleSelect ? (this.selectArr.length > 0 ? this.selectArr[0] : -1) : this.selectArr;
|
|||
|
this.$emit('onSelect', { index: index, row: thisRow });
|
|||
|
},
|
|||
|
// 返回表头标签内容
|
|||
|
getTitleText(col) {
|
|||
|
let tempHTML = '';
|
|||
|
if (col.titler) {
|
|||
|
tempHTML = col.titler();
|
|||
|
} else if (col.title) {
|
|||
|
tempHTML = col.title;
|
|||
|
} else {
|
|||
|
tempHTML = col.gTitle;
|
|||
|
}
|
|||
|
return tempHTML.toString();
|
|||
|
},
|
|||
|
//分页器点击事件
|
|||
|
paginationChange(e) {
|
|||
|
this.current = e.current;
|
|||
|
// console.log(JSON.stringify(e)+this.current);
|
|||
|
},
|
|||
|
//搜索内容提交事件
|
|||
|
onSearch(e) {
|
|||
|
//搜索内容为空的时候,默认全选
|
|||
|
if (e === '') {
|
|||
|
this.tableData.forEach((item, index) => {
|
|||
|
this.$set(item, 'rowSearch', true);
|
|||
|
});
|
|||
|
this.searchLen = this.tableData.length;
|
|||
|
this.pageSize = 100;
|
|||
|
return;
|
|||
|
}
|
|||
|
//过滤后的数据总行数
|
|||
|
var len = 0;
|
|||
|
this.tableData.forEach((item, index) => {
|
|||
|
//指定列过滤
|
|||
|
if (this.searchCol['index'] >= 0) {
|
|||
|
var cellVal = item[this.searchCol['key']] + '';
|
|||
|
if (cellVal.length > 0 && cellVal.indexOf(e) > -1) {
|
|||
|
this.$set(item, 'rowSearch', true);
|
|||
|
len += 1;
|
|||
|
} else {
|
|||
|
this.$set(item, 'rowSearch', false);
|
|||
|
}
|
|||
|
} else {
|
|||
|
//全列过滤
|
|||
|
this.$set(item, 'rowSearch', false);
|
|||
|
let exist = false;
|
|||
|
for (var i = 0; i < this.searchColData.length; i++) {
|
|||
|
//列集合中不存在field
|
|||
|
if (!this.searchColData[i]['field']) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
var cellVal = item[this.searchColData[i]['field']] + '';
|
|||
|
if (cellVal.length > 0 && cellVal.indexOf(e) > -1) {
|
|||
|
this.$set(item, 'rowSearch', true);
|
|||
|
exist = true;
|
|||
|
}
|
|||
|
}
|
|||
|
len += exist ? 1 : 0;
|
|||
|
}
|
|||
|
});
|
|||
|
this.searchLen = len;
|
|||
|
//查询后的数据不进行分页
|
|||
|
this.current = 1;
|
|||
|
this.pageSize = this.tableData.length;
|
|||
|
},
|
|||
|
//搜索清空按钮事件
|
|||
|
onSearchClear() {
|
|||
|
this.onSearch('');
|
|||
|
},
|
|||
|
// 展开查询框按钮事件
|
|||
|
buttonClick() {
|
|||
|
this.searchBoxTW = this.searchBoxTW === 0 ? 100 : 0;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss">
|
|||
|
.m-input-row {
|
|||
|
padding: 0;
|
|||
|
}
|
|||
|
|
|||
|
.pagination {
|
|||
|
// height: 10%;
|
|||
|
height: 33px;
|
|||
|
}
|
|||
|
|
|||
|
.navigator-hover {
|
|||
|
background: transparent;
|
|||
|
opacity: 1;
|
|||
|
}
|
|||
|
|
|||
|
@mixin ellipsis($num: 1) {
|
|||
|
overflow: hidden;
|
|||
|
text-overflow: ellipsis;
|
|||
|
|
|||
|
@if $num==1 {
|
|||
|
white-space: nowrap;
|
|||
|
} @else {
|
|||
|
display: -webkit-box;
|
|||
|
-webkit-line-clamp: $num;
|
|||
|
/* autoprefixer: off */
|
|||
|
-webkit-box-orient: vertical;
|
|||
|
/* autoprefixer: on */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 三角形
|
|||
|
%triangle-basic {
|
|||
|
content: '';
|
|||
|
height: 0;
|
|||
|
width: 0;
|
|||
|
overflow: hidden;
|
|||
|
}
|
|||
|
|
|||
|
@mixin triangle($direction, $size, $borderColor) {
|
|||
|
@extend %triangle-basic;
|
|||
|
|
|||
|
@if $direction==top {
|
|||
|
border-bottom: $size solid $borderColor;
|
|||
|
border-left: $size dashed transparent;
|
|||
|
border-right: $size dashed transparent;
|
|||
|
border-top: 0;
|
|||
|
} @else if $direction==right {
|
|||
|
border-left: $size solid $borderColor;
|
|||
|
border-top: $size dashed transparent;
|
|||
|
border-bottom: $size dashed transparent;
|
|||
|
border-right: 0;
|
|||
|
} @else if $direction==bottom {
|
|||
|
border-top: $size solid $borderColor;
|
|||
|
border-left: $size dashed transparent;
|
|||
|
border-right: $size dashed transparent;
|
|||
|
border-bottom: 0;
|
|||
|
} @else if $direction==left {
|
|||
|
border-right: $size solid $borderColor;
|
|||
|
border-top: $size dashed transparent;
|
|||
|
border-bottom: $size dashed transparent;
|
|||
|
border-left: 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
a {
|
|||
|
text-decoration: none;
|
|||
|
}
|
|||
|
|
|||
|
.z-table {
|
|||
|
position: relative;
|
|||
|
display: inline-block;
|
|||
|
height: 100%;
|
|||
|
width: 100%;
|
|||
|
min-height: 130rpx;
|
|||
|
background: #fff;
|
|||
|
border: solid 2rpx #ccc;
|
|||
|
font-size: $uni-font-size-sm;
|
|||
|
box-sizing: border-box;
|
|||
|
transform: translateZ(0);
|
|||
|
.z-table-main {
|
|||
|
height: 100%;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-pack {
|
|||
|
position: relative;
|
|||
|
min-height: 100%;
|
|||
|
width: fit-content;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-title {
|
|||
|
position: sticky;
|
|||
|
width: 100% !important;
|
|||
|
top: 0;
|
|||
|
min-height: 64rpx;
|
|||
|
z-index: 1;
|
|||
|
|
|||
|
.z-table-title-item {
|
|||
|
// border-bottom: solid 1rpx #dbdbdb;
|
|||
|
// border-right: solid 1rpx #dbdbdb;
|
|||
|
background: #f8f8f8;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-stick-side {
|
|||
|
position: sticky;
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
// border-right: solid 1rpx #dbdbdb;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.table-container-box.short-table {
|
|||
|
padding-bottom: 48rpx;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-title,
|
|||
|
.z-table-container-row {
|
|||
|
display: flex;
|
|||
|
width: fit-content;
|
|||
|
white-space: nowrap;
|
|||
|
box-sizing: border-box;
|
|||
|
|
|||
|
.z-table-title-item,
|
|||
|
.z-table-container-col {
|
|||
|
@include ellipsis();
|
|||
|
display: inline-flex;
|
|||
|
// padding: 0 3rpx;
|
|||
|
min-height: 64rpx;
|
|||
|
align-items: center;
|
|||
|
line-height: 64rpx;
|
|||
|
box-sizing: border-box;
|
|||
|
// flex-direction:column;
|
|||
|
// border-right: solid 1rpx #dbdbdb;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.z-table-container-row {
|
|||
|
z-index: 0;
|
|||
|
// border-bottom: solid 1rpx #f4f4f4;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-stick-side {
|
|||
|
position: sticky;
|
|||
|
left: 0;
|
|||
|
// background: #f7f9ff;
|
|||
|
// border-right: solid 1rpx #dbdbdb;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-bottom {
|
|||
|
position: absolute;
|
|||
|
bottom: 0;
|
|||
|
z-index: 9;
|
|||
|
display: flex;
|
|||
|
justify-items: center;
|
|||
|
width: fit-content;
|
|||
|
// background: #4298f7 !important;
|
|||
|
color: #fff !important;
|
|||
|
white-space: nowrap;
|
|||
|
box-sizing: border-box;
|
|||
|
|
|||
|
&.long-table {
|
|||
|
position: sticky;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-stick-side {
|
|||
|
background: #4298f7; //!important;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-bottom-col {
|
|||
|
display: inline-flex;
|
|||
|
align-items: center;
|
|||
|
text-align: center;
|
|||
|
padding: 16rpx 0 16rpx 0;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
|
|||
|
.z-table-bottom-text {
|
|||
|
line-height: 100%;
|
|||
|
box-sizing: border-box;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.table-empty {
|
|||
|
position: absolute;
|
|||
|
top: 64rpx;
|
|||
|
height: 64rpx;
|
|||
|
line-height: 64rpx;
|
|||
|
width: 100%;
|
|||
|
text-align: center;
|
|||
|
}
|
|||
|
|
|||
|
.sort {
|
|||
|
display: flex;
|
|||
|
padding: 5rpx;
|
|||
|
flex-direction: column;
|
|||
|
justify-content: center;
|
|||
|
|
|||
|
.up-arrow {
|
|||
|
@include triangle(top, 10rpx, #ccc);
|
|||
|
display: block;
|
|||
|
margin-bottom: 5rpx;
|
|||
|
|
|||
|
&.action {
|
|||
|
@include triangle(top, 10rpx, #4298f7);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.down-arrow {
|
|||
|
@include triangle(bottom, 10rpx, #ccc);
|
|||
|
display: block;
|
|||
|
|
|||
|
&.action {
|
|||
|
@include triangle(bottom, 10rpx, #4298f7);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 1.0.5
|
|||
|
.z-loading {
|
|||
|
position: absolute;
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
z-index: 2;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
justify-content: center;
|
|||
|
height: 100%;
|
|||
|
width: 100%;
|
|||
|
background: #fff;
|
|||
|
opacity: 0;
|
|||
|
transition: all 0.3s;
|
|||
|
|
|||
|
&.ztableLoading {
|
|||
|
opacity: 1;
|
|||
|
}
|
|||
|
|
|||
|
.z-loading-animate {
|
|||
|
position: relative;
|
|||
|
display: inline-block;
|
|||
|
width: 30rpx;
|
|||
|
height: 30rpx;
|
|||
|
margin-right: 20rpx;
|
|||
|
border-radius: 100%;
|
|||
|
border: solid 6rpx #ccc;
|
|||
|
vertical-align: middle;
|
|||
|
animation: rotate 1s ease-in-out infinite;
|
|||
|
|
|||
|
&::after {
|
|||
|
content: '';
|
|||
|
display: block;
|
|||
|
position: absolute;
|
|||
|
top: -10rpx;
|
|||
|
z-index: 1;
|
|||
|
background: #fff;
|
|||
|
width: 20rpx;
|
|||
|
height: 20rpx;
|
|||
|
border-radius: 10rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
@keyframes rotate {
|
|||
|
from {
|
|||
|
transform: rotate(0deg);
|
|||
|
}
|
|||
|
|
|||
|
to {
|
|||
|
transform: rotate(360deg);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 1.1.0 小复选框
|
|||
|
.select-box {
|
|||
|
display: inline-block;
|
|||
|
width: 30rpx;
|
|||
|
height: 30rpx;
|
|||
|
line-height: 14rpx;
|
|||
|
margin: 0 5rpx;
|
|||
|
border: solid 2rpx #4298f7;
|
|||
|
border-radius: 4rpx;
|
|||
|
background: #fff;
|
|||
|
text-align: center;
|
|||
|
}
|
|||
|
|
|||
|
.select-tip {
|
|||
|
display: inline-block;
|
|||
|
opacity: 0;
|
|||
|
transform: rotate(90deg);
|
|||
|
transition: all 0.3s;
|
|||
|
|
|||
|
&.selected {
|
|||
|
position: relative;
|
|||
|
top: 4rpx;
|
|||
|
left: -4rpx;
|
|||
|
height: 4rpx;
|
|||
|
background: #4298f7;
|
|||
|
width: 10rpx;
|
|||
|
opacity: 1;
|
|||
|
transform: rotate(45deg);
|
|||
|
|
|||
|
&:before,
|
|||
|
&:after {
|
|||
|
content: '';
|
|||
|
position: absolute;
|
|||
|
display: block;
|
|||
|
height: 4rpx;
|
|||
|
background: #4298f7;
|
|||
|
}
|
|||
|
|
|||
|
&:before {
|
|||
|
bottom: -2rpx;
|
|||
|
left: -4rpx;
|
|||
|
width: 8rpx;
|
|||
|
transform: rotate(-90deg);
|
|||
|
}
|
|||
|
|
|||
|
&:after {
|
|||
|
bottom: 16rpx;
|
|||
|
right: -16rpx;
|
|||
|
width: 34rpx;
|
|||
|
transform: rotate(-90deg);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 1.1.1
|
|||
|
.z-table-col-text {
|
|||
|
display: flex;
|
|||
|
width: 100%;
|
|||
|
height: 100%;
|
|||
|
flex: 1;
|
|||
|
justify-content: flex-start;
|
|||
|
align-content: center;
|
|||
|
|
|||
|
&.text-center {
|
|||
|
justify-content: center;
|
|||
|
}
|
|||
|
|
|||
|
&.text-right {
|
|||
|
justify-content: flex-end;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|