vue 自定义的通用的表格组件(使用div)
2023-12-21 23:41:02
vue 自定义的通用的表格组件(使用div)
做项目的时候由于传统的table及elementUI的el-table的tr和td没办法设置间距,满足不了UI提供的设计稿,为了还原,自己封装了该组件
该表格组件的特点
- 表头排序功能:支持点击表头进行升序、降序排序,并显示相应的排序图标。
- 复选框功能:可以在表格中为每一行数据添加复选框,并支持全选和取消全选操作。
- 图表展示:支持在表格中展示图表数据,提供相应的图表显示和交互功能。
- 文件上传功能:对于特定的列,支持文件上传和编辑操作,并可以显示上传进度和状态。
- 按钮操作:支持在表格中添加按钮并绑定相应的点击事件,实现自定义的操作功能(可以动态控制按钮的显示和禁用状态)。
- 支持单元格内容的格式化显示
- 行点击事件:支持点击表格某一行触发相应的事件处理。
- 包含了滚动条联动的功能,右侧侧固定列和表格内容的联动滚动
该表格组件的介绍
封装组件具体用了vue哪些指令
-
条件渲染
- 使用了 v-if 指令来根据条件判断是否渲染整个表格容器。
样式类绑定:
- 使用了 v-if 指令来根据条件判断是否渲染整个表格容器。
-
样式类绑定
- 使用了 :class 绑定动态的样式类。。
-
表头渲染:
- 使用了 v-for 指令循环渲染表头的每一列。
- 对每一列进行了样式设定,并且设置了点击事件处理函数。
-
表格内容渲染:
- 使用了 v-for 指令循环渲染表格的每一行和每一列。
- 对每个单元格进行了样式设定,并且设置了点击事件处理函数。
-
固定列:
- 在表格右侧实现了固定列的功能,并根据条件判断是否渲染固定列的内容。
-
事件处理:
- 使用了 @click 绑定点击事件处理函数。
- 使用了 @change 监听复选框的变化事件。
-
插槽:
- 使用了 slot 标签定义插槽,用于插入其他组件或内容。
表头部分
这部分代码负责渲染表格的表头结构,包括表头的各个列以及相关的操作按钮、排序功能等
<div class="common-table-header">
......
</div>
表格内容
这部分代码负责根据数据 data 动态渲染表格的行和列内容,包括每一行中的单元格内容、操作按钮、上传编辑功能等。
<div v-for="(row, index) in data">
......
</div>
类名介绍
- common-table-body — 表格内容的盒子(除表头外)高度需固定(固定原因:表格滚动条)
- common-table-body-wrapper — 表格内容的盒子(除表头外)高度自适应
- common-table-row — 每一行的类名
固定列部分
<div class="common-table-box-fixed">
......
</div>
传参介绍
- data — 表格显示的数据
- columns — 表格列字段
- 传参格式
- label对应value
- label2对应value1 — 这块后加的,value2被占用所以没对上可自行更改
- label3对应value3
- 传参格式
[{
label: '表头名称',
value: "对应列内容的字段名",
width: '表格列的宽度 --- 此处都是转化为vw以便自适应',
paddingLeft: '每一列的左内边距默认都为20',
paddingRight: '每一列的右内边距默认都为20',
isSort: '是否是索引',
position: "文字是位置-- center:居中;center-left:居左",
valueFormatter: "单元格内容的格式化显示---方法 --- 解析value",
valueFormatter1: "单元格内容的格式化显示---方法--- 解析value1",
valueFormatter3: "单元格内容的格式化显示---方法 --- 解析value3 ",
isHidden: '隐藏列',
isDate: '日期格式 --- 日期有特殊样式显示',
label2: '表头名称 --- 表格显示过多时一列支持显示1-3个字段,举例:表头名为姓名/性别/电话',
value1: '对应列内容的字段名 --- 表格显示过多时一列支持显示1-3个字段,举例:姓名/性别/电话竖着展示',
label3: '表头名称 --- 表格显示过多时一列支持显示1-3个字段,举例:表头名为姓名/性别/电话',
value3: '对应列内容的字段名 --- 表格显示过多时一列支持显示1-3个字段,举例:姓名/性别/电话竖着展示',
isTooltip: 是否超出显示提示框 --- value内容,
isTooltip1: 是否超出显示提示框 --- value1内容,
isTooltip2: 是否超出显示提示框 --- value3内容,
value2: '表格值显示。一般显示名称后value2用来拼接到value后的',
wordColor: '表格内容样色,默认为黑色,当该值为true则为灰色',
isCommonProgress: '显示进度条',
wrap: '通常用在操作列,按钮是否可以换行',
isButton: '代表渲染按钮',
buttonList: '按钮集合',
fontColorIsBlue: '文字颜色变为蓝色',
isbadge: '内容右上角显示的标记此处为数量',
isProgressVal: '进度,这块显示两行,上边为具体值,下册为百分比进度',
unit: '表格内容如果需要单位且不用valueFormatter,可直接使用该值进行传递',
isEcharts: '需要绘制echarts',
isImg: '代表需要展示图片',
question: '表头显示提示框解释该字段表格含义',
isClick: '表格可以点击需结合callback进行使用,只有点击每一列生效',
callback: '方法,点击表格某行后执行',
bgFormatter: '方法,根据某个值给表格行添加背景'
}]
- 举例
tableColumns = [
{
label: "序号",
value: "sort",
width: this.windowWidth <= 1024 ? 70 * 2 : 78 * 2,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
isSort: true,
position: "center"
},
{
label: "创建日期",
value: "createTime",
isDate: true,
width: this.windowWidth <= 1024 ? 140 * 2 : 148 * 2,
position1: "center-left",
valueFormatter: this.valueDateFormat,
paddingLeft: 0,
paddingRight: 0,
isHidden: this.windowWidth <= 1024
},
{
label: "类型",
value: "type",
width: this.windowWidth <= 1024 ? 85 * 2 : 107 * 2,
position: "center",
valueFormatter: this.valueSourceFormat,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2
},
];
- isJump
- 点击表格任意行及任意位置都能触发
- isChoose
- 支持选中某一行
- needJudgeChooseStatus
- false-任意选;true-需要满足某些条件才能被选
- buttonList
- 固定操作列按钮集合
- fixedWidth
- 固定操作列宽
- fixedLabel
- 固定操作表头的label
- rowId
- 选中某一行时判断是否重复选择的属性key
- isScroll
- 是否支持滚动表格后才加载某些内容
- checkDisabledLabel
- 表格多选框是否禁用要判断的属性key
- titleCheck
- 表格表头多选框的绑定值
- titleChekcDisabled
- 表格表头多选框是否禁用
- chooseNumber
- 选中表格行最多支持的数量
- chooseTooltip
- 选中表格行等于支持的数量后再选的提示
方法介绍
- handleClickSort(handleSortDown,handleSortUp)
- 表格的列头点击时触发排序操作,调用 $emit 方法来触发排序事件,并将排序方式和排序字段作为参数传递给父组件,供其进行相应的处理。
- handleChangeCheck
- 调用 $emit 方法触发勾选事件,将当前行的row作为参数传递给父组件
- handleChangeCheckAll
- 代表全选当前页 - 调用 $emit 方法触发勾选事件传递给父组件
- progressoFormat
- 用于格式化进度条的显示文本。该方法接收两个参数:percentage 表示进度百分比,status 表示进度状态
- handleAvatarSuccess
上传文件调用的方法
- res-表示上传成功的响应对象
- index-表示索引值
- row 表示行信息。
- beforeAvatarUpload
上传文件判断文件类型和大小,根据条件决定是否压缩文件,并将结果返回给上传组件。同时,也会触发上传事件,并将索引值传递给父组件。
- getFontColorIsBlue(getFontColorIsBlue1,getFontColorIsBlue2)
- 判断是否给表格某列的添加类名,对文字颜色进行改变
- getColumnValue(getColumnValue1,getColumnValue3)
- 用来格式化内容
- getColumnBg
- 判断是否给该行添加背景类名
- getColumnClass(getColumnClass1,getColumnClass2)
- 判断是否给该行添加文字类名
- getWidth
- 设置每一列宽度
- getPadding
- 设置每一列内间距
- getButtonDisabled
- 判断按钮是否禁用
- getButtonDisplay
- 判断按钮是否隐藏显示
- handleJudgeOperate
- 判断该列是否隐藏显示
- handleListenerScroll
- 表格滚动事件
- combinedScroll
- 右侧侧固定列和表格内容的联动滚动
- handleClickRow
- 点击某一行
- clearChooseData
- 清除选中的内容
完整代码
commonTable.vue
<template>
<div
class="h-common-table-container"
v-if="data.length > 0"
>
<div
class="common-table-box"
>
<div class="common-table-box-wrapper">
<div class="common-table-header">
<div
v-for="(column, index) in columns"
:key="index"
:style="[
{ width: getWidth(column.width, column) },
{ textAlign: column.position || 'left' },
{
paddingLeft:
column.position != 'center' && getPadding(column.paddingLeft)
},
{
paddingRight:
column.position == 'right' && getPadding(column.paddingRight)
},
{
display: column.isCheckBox ? 'flex' : '',
justifyContent: column.isCheckBox ? 'center' : '',
alignItems: column.isCheckBox ? 'center' : ''
}
]"
:class="[
{ 'no-padding': column.position == 'center' },
{
'padding-right': column.isButton && column.position == 'right'
},
{ 'column-flex': column.sort },
{ 'column-date': column.isDate }
]"
v-show="handelJudgeFixed(column) && !column.isHidden"
@click.stop="handleClickSort(column)"
>
<el-checkbox
v-if="column.isCheckBox"
:disabled="titleChekcDisabled"
v-model="titleCheck"
@change="handleChangeCheckAll($event, columns)"
></el-checkbox>
<span class="column-label" v-if="!column.isCheckBox">{{
column.label
}}</span>
<span class="column-label-another" v-if="column.label2">{{
column.label2
}}</span>
<div class="sort-box" v-if="column.sort">
<span @click.stop="handleSortUp(column)"
><img
src="@/assets/img/up.png"
alt=""
v-if="sortValue != 1"/><img
src="@/assets/img/upChoose.png"
alt=""
v-if="sortValue == 1"
/></span>
<span @click.stop="handleSortDown(column)"
><img
src="@/assets/img/down.png"
alt=""
v-if="sortValue != 2"/><img
src="@/assets/img/downChoose.png"
alt=""
v-if="sortValue == 2"
/></span>
</div>
<el-popover
placement="right"
style="display: inline-block"
v-if="column.question"
:popper-class="
$store.getters.windowWidth <= 1024
? 'popover-toolip popover-toolip-wdith'
: 'popover-toolip'
"
ref="popover"
trigger="hover"
>
<slot name="content"></slot>
<i class="el-icon-question mgl10 pointer" slot="reference"></i>
</el-popover>
</div>
</div>
<div
class="common-table-body common-scroll"
>
<div
class="common-table-body-wrapper"
>
<div
v-for="(row, index) in data"
:key="index + 'row'"
class="common-table-row"
@click="handleClickRow(row)"
:class="[
chooseList.some(val => val[rowId] === row[rowId])
? 'row-is-active'
: '',
isChoose || isJump ? 'common-table-row-choose' : '',
row.isRequire ? 'row-border-red' : ''
]"
>
<div
v-for="(column, indexColumns) in columns"
:key="indexColumns + 'column'"
:style="[
{ width: getWidth(column.width, column, row) },
{ paddingLeft: getPadding(column.paddingLeft) },
{ paddingRight: getPadding(column.paddingRight) }
]"
class="cell-box"
:class="[
{ 'has-border': column.hasBorder },
{
'word-center':
(column.position == 'center' && !column.isButton) ||
(column.position1 == 'center' && column.isButton)
},
{ 'word-center-left': column.position1 == 'center-left' },
{ 'word-center-right': column.position1 == 'center-right' },
{ 'button-center-right': column.position1 == 'right' },
{ 'chart-padding': column.isEcharts },
{ 'cell-padding': $store.getters.isNormal },
{ 'cell-padding-no-top': column.noPaddingTop },
{
'cell-padding-no':
$store.getters.windowWidth <= 1024 && column.isButton
},
{ 'cell-padding-min': column.wrap }
]"
v-show="handleJudgeOperate(column, row) && !column.isHidden"
>
<div
v-if="column.isEcharts"
style="width: 100%; position: relative; height: 100%"
>
<div
v-myLoading="JSON.stringify(row.echarts) == '{}'"
class="echarts-top"
v-if="JSON.stringify(row.echarts) == '{}'"
></div>
<chart
:chart-data="row.echarts"
:className="'table-chart'"
v-else
/>
</div>
<div v-else-if="column.isOpera" class="row-label">
<div>操作</div>
</div>
<div
v-else-if="column.isSort"
class="row-label"
:style="[
{
textAlign: column.position1 || column.position || 'left'
}
]"
>
<div>{{ index + 1 }}</div>
</div>
<div
v-else-if="column.isCheckBox"
class="row-label"
style="height: 100%; display: flex; justify-content: center"
>
<el-checkbox
:disabled="row[checkDisabledLabel] == 1"
v-model="row.isCheckd"
@change="handleChangeCheck($event, row)"
></el-checkbox>
</div>
<div
v-else-if="column.isProgress"
class="row-label"
style="position: relative"
>
<el-progress
:text-inside="true"
:stroke-width="26"
:percentage="row.percentage"
:status="row.status"
:format="
() => {
return progressoFormat(row.percentage, row.status);
}
"
:class="
$store.getters.windowWidth <= 1024
? 'el-progress-width'
: ''
"
></el-progress>
<span
class="progress-label"
:class="
$store.getters.windowWidth <= 1024
? 'progress-label-width'
: ''
"
v-if="row.percentage == 0"
>未上传</span
>
</div>
<div
v-else-if="column.isProgressVal"
class="row-label"
style="position: relative"
>
<div class="progress-box">
<div class="device-num">
{{ row.shipmentNum }}/{{ row.totalShipmentNum }}台
</div>
<div class="progress" v-if="row.percent != '-'">
<div
:style="[
{
width: row.percent
}
]"
class="progress-color"
></div>
<div class="val">{{ row.percent }}</div>
</div>
<div
class="progress"
style="background: transparent;"
v-else
>
{{ row.percent }}
</div>
</div>
</div>
<div
v-else-if="column.isCommonProgress"
class="row-label"
style="position: relative"
>
<div class="common-progress-box">
<div
:style="[
{
width: row[column.value] +'%'
}
]"
class="progress-bg-color"
></div>
<div class="val">{{ row[column.value]+'%' }}</div>
</div>
</div>
<div
v-else-if="column.isUpload"
class="row-label row-label-upload"
>
<el-upload
v-if="row.key != 'monitor-info' && !row.isHas"
action="#"
:before-upload="
e => {
beforeAvatarUpload(e, index, row.key);
}
"
:show-file-list="false"
:http-request="
e => {
handleAvatarSuccess(e, index, row);
}
"
:on-progress="uploadProcess"
:disabled="column.disabled"
>
<el-button
class="table-button-upload"
type="info"
:disabled="column.disabled"
:class="buttonClass.tableButton"
>
<span>上传编辑</span></el-button
>
</el-upload>
<el-button
v-else
class="table-button-upload"
type="info"
:disabled="column.disabled"
:class="buttonClass.tableButton"
@click="$emit('special', row)"
>
<span>查看编辑</span></el-button
>
</div>
<div v-else-if="column.isImg" class="row-label">
<div
style="
display: flex;
align-items: center;
justify-content: center;
"
v-if="getColumnValue(column, row)"
>
<img :src="getColumnValue(column, row)" alt="" />
</div>
</div>
<div
v-else-if="column.isButton"
class="button-flex-box"
:class="[
column.position1 == 'center'
? 'button-flex-box-padding'
: '',
column.nowrap ? 'button-flex-box-nowarp' : '',
column.wrap ? 'button-flex-box-wrap' : '',
column.isSmall ? 'button-flex-box-small' : '',
column.marginR?'button-flex-box-mr':''
]"
>
<!-- <div>
<el-button
type="success"
:disabled="getButtonDisabled(column.disabled,row)"
:class="buttonClass.tableButton"
class="table-button"
@click="column.callback(row)"
v-if="getButtonDisplay(column.display, row)"
><span> {{ column.caption }} </span></el-button
>
</div> -->
<!-- :class="$store.getters.isNormal ? 'button-Box-height' : ''"-->
<div
class="button-Box button-Box-height"
v-for="(item, parentIndex) in column.buttonList"
:key="parentIndex + 'parent'"
>
<template
v-for="({ display, type, callback, caption, disabled,loading },
childIndex) in item"
>
<el-button
:disabled="getButtonDisabled(disabled, row)"
:key="childIndex + caption + 'child'"
v-if="getButtonDisplay(display, row)"
:type="type"
:loading="loading===undefined?false:loading==row.id"
:class="[
buttonClass.tableButton,
caption.length == 4 ? 'button-four' : ''
]"
class="table-button"
@click.stop="callback(row, index)"
>{{ caption }}
</el-button>
</template>
</div>
</div>
<div
v-else-if="column.isuploadButton"
class="button-flex-box one"
:class="
column.position == 'center' ? 'button-flex-box-padding' : ''
"
>
<div
class="button-Box file-button-box"
v-for="(item, parentIndex) in column.buttonList"
:key="parentIndex + 'parent'"
:class="$store.getters.isNormal ? 'button-Box-height' : ''"
>
<template
v-for="({
display,
type,
callback,
caption,
isUpload,
disabled
},
childIndex) in item"
>
<template
v-if="isUpload && getButtonDisplay(display, row)"
>
<el-upload
:key="childIndex + caption + 'child1'"
v-if="row.key == 'project-info' && !row.isHas"
action="#"
:before-upload="
e => {
beforeAvatarUpload(e, index, row.key);
}
"
:show-file-list="false"
:http-request="
e => {
handleAvatarSuccess(e, index, row);
}
"
:on-progress="uploadProcess"
:disabled="column.disabled"
>
<el-button
class="table-button-upload"
type="info"
:disabled="column.disabled"
:class="buttonClass.tableButton"
>
<span>{{ caption }}</span></el-button
>
</el-upload>
<el-button
v-else
:key="childIndex + caption + 'child2'"
class="table-button-upload"
type="info"
:disabled="column.disabled"
:class="buttonClass.tableButton"
@click="$emit('special', row)"
>
<span>查看</span></el-button
>
</template>
<el-button
:disabled="getButtonDisabled(disabled, row)"
:key="childIndex + caption + 'child'"
v-else-if="!isUpload && getButtonDisplay(display, row)"
:type="type"
:class="[
buttonClass.tableButton,
caption.length == 4 ? 'button-four' : ''
]"
class="table-button"
@click.stop="callback(row, index)"
>{{ caption }}
</el-button>
</template>
</div>
</div>
<div
v-else-if="column.isClick"
style="cursor: pointer"
class="row-label"
@click="column.callback(row, column)"
>
<div
:style="[
{
textAlign: column.position1 || column.position || 'left'
}
]"
:class="[
{ 'word-bold': column.wordBold },
{ 'word-font-default': column.wordFontDefault },
{ 'word-blue': getFontColorIsBlue(column, row) },
column.value1 ? 'no-warp' : 'one-line',
getColumnBg(column, row),
getColumnClass(column, row)
]"
>
<common-tooltip
:twoLine="column.isTooltip && column.value1 != undefined"
:className="'ellipsisName' + indexColumns"
:refName="'toolitipName' + indexColumns"
:content="getColumnValue(column, row)"
:disabled="!column.isTooltip"
>
</common-tooltip>
</div>
<div
v-if="column.value1"
:style="[{ textAlign: column.position || 'left' }]"
:class="[
{ 'word-bold': column.wordBold1 },
{ 'row-label-color-default': column.wordColorDefault1 },
{ 'word-blue': getFontColorIsBlue1(column, row) },
column.value3 ? 'two-line-mt' : '',
getColumnBg(column, row),
getColumnClass1(column, row)
]"
class="two-line"
>
<common-tooltip
:twoLine="column.isTooltip1"
:className="'ellipsisNameTwo' + indexColumns"
:refName="'toolitipNameTwo' + indexColumns"
:content="getColumnValue1(column, row)"
:disabled="!column.isTooltip1"
>
</common-tooltip>
</div>
<div
v-if="column.value3"
:style="[{ textAlign: column.position || 'left' }]"
:class="[
{ 'word-bold': column.wordBold2 },
{ 'word-blue': getFontColorIsBlue2(column, row) },
getColumnBg(column, row),
getColumnClass2(column, row)
]"
class="two-line two-line-mts"
>
<common-tooltip
:twoLine="column.isTooltip2"
:className="'ellipsisNameThree' + indexColumns"
:refName="'toolitipNameThree' + indexColumns"
:content="getColumnValue3(column, row)"
:disabled="!column.isTooltip2"
>
</common-tooltip>
</div>
</div>
<template v-else-if="column.isbadge">
<el-badge
:value="row.badgeNum > 99 ? 99 : row.badgeNum"
class="item"
:hidden="row.badgeNum == 0"
>
{{ getColumnValue(column, row) }}
</el-badge>
</template>
<div
v-else
class="row-label"
:class="column.isDate ? 'row-label-date' : ''"
>
<div
:style="[
{
textAlign: column.position1 || column.position || 'left'
}
]"
:class="[
{ 'word-bold': column.wordBold },
{ 'word-font-default': column.wordFontDefault },
{ 'word-blue': getFontColorIsBlue(column, row) },
column.value1 ? 'no-warp' : 'one-line',
column.wordColor ? 'row-label-color' : '',
column.isDeviceNum
? column.boxBg(row) == 'danger'
? 'row-label-num-style row-label-num-style-bg'
: 'row-label-num-style'
: '',
column.isCircle ? 'row-label-circle' : '',
getColumnBg(column, row),
getColumnClass(column, row)
]"
>
<common-tooltip
:twoLine="column.isTooltip && column.value1 != undefined"
:className="'ellipsisName' + indexColumns"
:refName="'toolitipName' + indexColumns"
:content="getColumnValue(column, row)"
:disabled="!column.isTooltip"
>
</common-tooltip>
</div>
<div
v-if="column.value1"
:style="[{ textAlign: column.position || 'left' }]"
:class="[
{'row-label-color':column.wordColor1},
{ 'word-bold': column.wordBold1 },
{ 'row-label-color-default': column.wordColorDefault1 },
{ 'word-blue': getFontColorIsBlue1(column, row) },
column.value3 ? 'two-line-mt' : '',
getColumnBg(column, row),
getColumnClass1(column, row)
]"
class="two-line"
>
<common-tooltip
:twoLine="column.isTooltip1"
:className="'ellipsisNameTwo' + indexColumns"
:refName="'toolitipNameTwo' + indexColumns"
:content="getColumnValue1(column, row)"
:disabled="!column.isTooltip1"
>
</common-tooltip>
</div>
<div
v-if="column.value3"
:style="[{ textAlign: column.position || 'left' }]"
:class="[
{ 'word-bold': column.wordBold2 },
{ 'word-blue': getFontColorIsBlue2(column, row) },
getColumnBg(column, row),
getColumnClass2(column, row)
]"
class="two-line two-line-mts"
>
<common-tooltip
:twoLine="column.isTooltip2"
:className="'ellipsisNameThree' + indexColumns"
:refName="'toolitipNameThree' + indexColumns"
:content="getColumnValue3(column, row)"
:disabled="!column.isTooltip2"
>
</common-tooltip>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="common-table-box-fixed"
v-if="buttonList.length > 0 && data.length > 0 && handelJudgeFixed()"
:style="{ width: getWidth(fixedWidth) }"
>
<div class="common-table-fixed-header" style="width: 100%">
{{ fixedLabel }}
</div>
<div
class="common-table-fixed-box common-scroll"
:class="$store.getters.windowWidth <= 1024 ? 'common-scroll-width' : ''"
>
<div class="common-table-fixed-wrapper">
<div
class="common-table-fixed-header-body"
v-for="(row, index) in data"
:key="index + 'fixed'"
:class="[
chooseList.some(val => val[rowId] === row[rowId])
? 'fixed-is-active'
: '',
isChoose || isJump ? 'common-table-fixed-row-choose' : '',
isOne ? 'common-table-fixed-header-body-flex' : ''
]"
@click.stop="handleClickRow(row)"
>
<div
class="button-Box"
v-for="(item, parentIndex) in buttonList"
:key="parentIndex + 'parent'"
:class="$store.getters.isNormal ? 'button-Box-height' : ''"
>
<template
v-for="({ display, type, callback, caption },
childIndex) in item"
>
<el-button
:key="childIndex + caption + 'child'"
v-if="getButtonDisplay(display, row)"
:type="type"
:class="[
buttonClass.tableButton,
caption.length == 4 ? 'button-four' : ''
]"
class="table-button"
@click.stop="callback(row, index)"
>{{ caption }}
</el-button>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import chart from "@/components/echarts/index";
import commonSearchMixin from "@/mixins/search";
import commonTooltip from "@/components/commonTooltip/index";
import { uploadImgProgress } from "@/api/district";
export default {
name: "HTable",
mixins: [commonSearchMixin],
props: {
data: Array,
columns: Array,
isJump: {
type: Boolean,
default: false
},
isChoose: {
type: Boolean,
default: false
},
needJudgeChooseStatus: {
type: Function,
default: () => {
return false;
}
},
buttonList: {
type: Array,
default: () => {
return [];
}
},
fixedWidth: {
type: Number,
default: 85 * 2
},
fixedLabel: {
type: String,
default: "操作"
},
rowId: {
type: String,
default: "id"
},
isScroll: {
type: Boolean,
default: false
},
isOne: {
type: Boolean,
default: false
},
checkDisabledLabel: {
type: String,
default: "needAttest"
},
titleCheck: {
type: Boolean,
default: false
},
titleChekcDisabled: {
type: Boolean,
default: false
},
chooseNumber: {
type: [Number, String],
default: 5
},
chooseTooltip: {
type: String,
default: "最多支持选择5条数据进行数据对比!"
}
},
data() {
return {
chooseList: [],
isFlag: false,
sortUp: false,
sortdown: false,
sortValue: 0
// isFlag: false,
};
},
watch: {
data: {
handler(val) {
if (val.length > 0) {
if (!this.isFlag) {
this.isFlag = true;
this.$nextTick(() => {
var bodyBox = document.querySelector(".common-table-body");
if (bodyBox) {
this.handleListenerScroll();
}
});
}
} else {
this.isFlag = false;
}
},
immediate: true,
deep: true
},
windowWidth: {
handler(val) {
this.$nextTick(() => {
var bodyBox = document.querySelector(".common-table-body");
if (bodyBox) {
this.handleListenerScroll();
}
});
},
immediate: true
}
},
components: { chart, commonTooltip },
computed: {
windowWidth() {
return this.$store.getters.windowWidth;
}
},
methods: {
handleClickSort(column) {
if (column.sort) {
if (this.sortValue == 2) {
this.sortValue = 0;
this.$emit("sort", "none", "");
} else if (this.sortValue == 1) {
this.$emit("sort", "down", column.value);
this.sortValue = 2;
} else {
this.$emit("sort", "up", column.value);
this.sortValue = 1;
}
}
},
handleSortDown(column) {
this.$emit("sort", "down", column.value);
this.sortValue = 2;
},
handleSortUp(column) {
this.$emit("sort", "up", column.value);
this.sortValue = 1;
},
handleChangeCheck(val, row) {
this.$emit("checked", row);
},
handleChangeCheckAll() {
this.$emit("checkedAll");
},
progressoFormat(percentage, status) {
if (percentage === 100) {
if (status == "success") {
return "已完成";
} else if (status == "exception") {
return "上传失败";
} else if (status == "exception") {
return `${percentage}%`;
}
} else if (percentage === 0) {
return ``;
} else {
return `${percentage}%`;
}
},
uploadProcess(event, file, fileList) {},
handleAvatarSuccess(res, index, row) {
const isJPG =
res.file.type === "image/jpeg" || res.file.type === "image/png";
if (row.key == "project-info" && !isJPG) {
this.$commonMessage.message({
type: "warning",
message: "请上传PNG或JPG格式的图片!"
});
return false;
}
// 以下是向后端识别图片接口传递file文件
var formData = new FormData();
formData.append("file", res.file); // 注意是传file.raw
const uploadProgressEvent = progressEvent => {
let percent = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
res.onProgress({ percent: percent, status: "" });
this.$emit("progress", { percent: percent, status: "warning" }, index);
};
uploadImgProgress(formData, uploadProgressEvent)
.then(response => {
this.$emit(
"success",
{
percent: 100,
status: "success",
data: response,
row: row
},
index
);
res.onProgress({ percent: 100, status: "success" }, index);
})
.catch(() => {
res.onProgress({ percent: 100, status: "exception" });
this.$emit(
"fail",
{ percent: 100, status: "exception", row: row },
index
);
});
},
beforeAvatarUpload(file, index, key) {
const isJPG = file.type === "image/jpeg" || file.type === "image/png";
if (key == "project-info" && !isJPG) {
return false;
}
this.$emit("upload", index);
const isLtM = file.size / 1024 / 1024 >= 1;
if (isJPG) {
return new Promise(resolve => {
// 小于1M 不压缩
if (!isLtM) {
resolve(file);
}
// 压缩到400KB,这里的400就是要压缩的大小,可自定义
this.imageConversion.compressAccurately(file, 400).then(res => {
resolve(res);
});
//compressAccurately有多个参数时传入对象
//imageConversion.compressAccurately(file, {
// size: 1024, //图片大小压缩到1024kb
// width:1280 //宽度压缩到1280
//}).then(res => {
//resolve(res)
//})
});
} else {
return true;
}
},
getFontColorIsBlue(column, row) {
let { fontColorIsBlue } = column;
if (row) {
if (fontColorIsBlue && typeof fontColorIsBlue === "function") {
return fontColorIsBlue(row);
} else {
return fontColorIsBlue;
}
}
},
getFontColorIsBlue1(column, row) {
let { fontColorIsBlue1 } = column;
if (row) {
if (fontColorIsBlue1 && typeof fontColorIsBlue1 === "function") {
return fontColorIsBlue1(row);
} else {
return fontColorIsBlue1;
}
}
},
getFontColorIsBlue2(column, row) {
let { fontColorIsBlue2 } = column;
if (row) {
if (fontColorIsBlue2 && typeof fontColorIsBlue2 === "function") {
return fontColorIsBlue2(row);
} else {
return fontColorIsBlue2;
}
}
},
getProgressSuccess(column, row) {
if (row.percentage == 100) {
return "success";
}
},
getColumnValue(column, row) {
let { value, valueFormatter, unit, value2 } = column;
if (row) {
if (valueFormatter && typeof valueFormatter === "function") {
return valueFormatter(row, value);
} else {
if (value2) {
return (
row[value] +
(row[value] !== undefined && row[value] !== null && unit
? unit
: "") +
"-" +
row[value2]
);
} else {
return (
(row[value] !== undefined && row[value] !== null
? row[value]
: "-") + (row[value] && unit ? unit : "")
);
}
}
}
},
getColumnBg(column, row) {
let { bgFormatter } = column;
if (row) {
if (bgFormatter && typeof bgFormatter === "function") {
return bgFormatter(row);
}
return "";
}
},
getColumnClass(column, row) {
let { fontColorIsRed } = column;
if (row) {
if (fontColorIsRed && typeof fontColorIsRed === "function") {
return fontColorIsRed(row);
}
return "";
}
},
getColumnClass1(column, row) {
let { fontColorIsRed1 } = column;
if (row) {
if (fontColorIsRed1 && typeof fontColorIsRed1 === "function") {
return fontColorIsRed1(row);
}
return "";
}
},
getColumnClass2(column, row) {
let { fontColorIsRed1 } = column;
if (row) {
if (fontColorIsRed1 && typeof fontColorIsRed1 === "function") {
return fontColorIsRed1(row);
}
return "";
}
},
getColumnValue1(column, row) {
let { value1, valueFormatter1, unit1 } = column;
if (row) {
if (valueFormatter1 && typeof valueFormatter1 === "function") {
return valueFormatter1(row, value1);
} else {
return (
(row[value1] ? row[value1] : "") +
(row[value1] && unit1 ? unit1 : "")
);
}
}
},
getColumnValue3(column, row) {
let { value3, valueFormatter3, unit2 } = column;
if (row) {
if (valueFormatter3 && typeof valueFormatter3 === "function") {
return valueFormatter3(row, value3);
} else {
return (
(row[value3] ? row[value3] : "") +
(row[value3] && unit2 ? unit2 : "")
);
}
}
},
getWidth(val, column, row) {
if (!this.handelJudgeFixed()) {
if (column && column.addWidth) {
if (this.$store.getters.windowWidth <= 1024) {
return (((column.addWidth / 1024) * 1920) / 3840) * 2 * 100 + "vw";
} else {
return (column.addWidth / 3840) * 2 * 100 + "vw";
}
}
}
if (this.$store.getters.windowWidth <= 1024) {
return (((val / 1024) * 1920) / 3840) * 2 * 100 + "vw";
} else {
return (val / 3840) * 2 * 100 + "vw";
}
},
getPadding(val = 40) {
if (this.$store.getters.windowWidth <= 1024) {
return (((val / 1024) * 1920) / 3840) * 2 * 100 + "vw";
} else {
return (val / 3840) * 2 * 100 + "vw";
}
},
getButtonDisabled(display, row) {
let result = false;
if (typeof display === "boolean") {
result = display;
} else if (typeof display === "function") {
result = display(row);
}
return result;
},
getButtonDisplay(display, row) {
let result = true;
if (typeof display === "boolean") {
result = display;
} else if (typeof display === "function") {
result = display(row);
}
return result;
},
handleJudgeOperate(column, row) {
if (column.isOpera) {
return this.handelJudgeFixed();
} else {
return true;
}
},
handelJudgeFixed(column) {
if (column && !column.isOpera) {
return true;
}
let result = false;
for (let k = 0; k < this.buttonList.length; k++) {
if (this.buttonList[k].some(row => row.display !== undefined)) {
result = this.buttonList[k].some(row => row.display !== undefined);
}
}
if (result) {
let flag = false;
for (let i = 0; i < this.buttonList.length; i++) {
for (let j = 0; j < this.buttonList[i].length; j++) {
if (typeof this.buttonList[i][j].display === "boolean") {
if (this.buttonList[i][j].display) {
flag = this.buttonList[i][j].display;
}
} else if (typeof this.buttonList[i][j].display === "function") {
if (
!flag &&
this.data.some(el => {
return this.buttonList[i][j].display(el);
})
) {
flag = true;
}
}
}
}
return flag;
} else {
return true;
}
},
handleListenerScroll() {
let that = this;
var bodyBox = document.querySelector(".common-table-body");
function bindEventLeft() {
bodyBox.addEventListener("scroll", leftScroll);
}
function removeEventLeft() {
bodyBox.removeEventListener("scroll", leftScroll);
}
function leftScroll() {
var a = bodyBox.scrollTop;
if (that.isScroll) {
that.$emit("scroll", a);
}
}
bodyBox.addEventListener("mouseover", bindEventLeft);
bodyBox.addEventListener("mouseLeave", removeEventLeft);
},
combinedScroll() {
let that = this;
// 获取元素
var bodyBox = document.querySelector(".common-table-body");
var fixedBox = document.querySelector(".common-table-fixed-box");
// 绑定body的滚动事件
function bindEventLeft() {
removeEventRight(); //关键点-先解绑右边
bodyBox.addEventListener("scroll", leftScroll);
}
// 绑定fixed的滚动事件
function bindEventRight() {
removeEventLeft(); //关键点-先解绑左边
fixedBox.addEventListener("scroll", rightScroll);
}
// 解绑body的滚动事件
function removeEventLeft() {
bodyBox.removeEventListener("scroll", leftScroll);
}
// 解绑fixed的滚动事件
function removeEventRight() {
fixedBox.removeEventListener("scroll", rightScroll);
}
// body滚动时候,fixed同步
function leftScroll() {
var a = bodyBox.scrollTop;
fixedBox.scrollTop = a;
if (that.isScroll) {
that.$emit("scroll", a);
}
}
// fixed滚动时候,body同步
function rightScroll() {
var a = fixedBox.scrollTop;
bodyBox.scrollTop = a;
if (that.isScroll) {
that.$emit("scroll", a);
}
}
bodyBox.addEventListener("mouseover", bindEventLeft);
fixedBox.addEventListener("mouseover", bindEventRight);
},
handleClickRow(value) {
if (!this.isChoose && !this.isJump) {
return;
}
if (this.isChoose) {
if (this.needJudgeChooseStatus(value)) {
this.$commonMessage.message({
type: "info",
message: this.needJudgeChooseStatus(value)
});
return;
}
let type = 'add'
// 增加
if (
!this.chooseList.some(row => row[this.rowId] === value[this.rowId])
) {
if(this.chooseNumber != 'unlimited') {
if (this.chooseList.length == this.chooseNumber) {
this.$commonMessage.message({
type: "info",
message: this.chooseTooltip
});
return;
}
}
type = 'add'
this.chooseList.push(value);
} else {
type = 'delete'
this.chooseList.splice(
this.chooseList.findIndex(
row => row[this.rowId] === value[this.rowId]
),
1
);
}
this.$emit("getChooseData", this.chooseList,type, value[this.rowId]);
} else {
this.$emit("jump", value);
}
},
clearChooseData() {
this.chooseList = [];
this.$emit("getChooseData", this.chooseList);
}
},
mounted() {
this.$nextTick(() => {
var bodyBox = document.querySelector(".common-table-body");
if (bodyBox) {
this.handleListenerScroll();
}
});
}
};
</script>
<style lang="scss" scoped>
.h-common-table-container {
flex-direction: column;
}
</style>
<style lang="scss"></style>
- chart:详见该篇文章vue elementUI el-select的封装vue 封装echarts
- commonTooltip:详见该篇文章Vue tooltip 组件封装
index.scss
.h-common-table-container {
position: relative;
height: calc(100% - 3.125vw);
display: flex;
flex-direction: column;
.common-table-box {
background-color: transparent;
border-radius: 0;
border: none;
@include font_color("themeColor");
font-size: vw(14 * 2);
margin-bottom: vh(40 * 2);
height: 100%;
width: 100%;
overflow-y: hidden;
overflow-x: auto;
padding-bottom: vh(6 * 2);
&.common-table-box-min {
height: vh(288 * 2);
padding-bottom: 0;
margin-bottom: 0;
}
&.common-table-box-min-height {
height: vh(322 * 2);
padding-bottom: 0;
margin-bottom: 0;
}
&::-webkit-scrollbar {
width: vw(6 * 2);
height: vw(6 * 2);
}
/*定义滑块 内阴影+圆角*/
&::-webkit-scrollbar-thumb {
background-color: #dfdfdf;
border-radius: vw(3 * 2);
}
&::-webkit-scrollbar-track {
background: #fff;
border-radius: vw(3 * 2);
}
.common-table-box-wrapper {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.common-table-header {
height: vh(25 * 2);
display: flex;
margin-bottom: vh(20 * 2);
font-size: vw(18 * 2);
color: #000;
font-weight: 500;
div {
height: 100%;
text-align: center;
flex-shrink: 0;
padding-left: vw(20 * 2);
&.no-padding {
padding-left: 0;
}
&.padding-right {
padding-right: vw(50 * 2) !important;
}
&.column-flex {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
&.column-date {
padding-left: vw(35 * 2) !important;
}
.sort-box {
display: inline-flex;
flex-direction: column;
padding-left: 0;
align-items: center;
justify-content: center;
span {
width: vw(12 * 2);
margin-bottom: vh(1 * 2);
cursor: pointer;
// height: vw(8*2);
display: flex;
align-items: center;
justify-content: center;
&:last-child {
margin-bottom: 0;
}
img {
width: 100%;
height: 100%;
}
}
}
.el-checkbox {
width: fit-content;
padding: 0 vw(20 * 2);
display: inline-flex;
align-items: center;
height: 100%;
font-size: vw(12 * 2);
margin-right: 0;
.el-checkbox__label {
font-size: vw(12 * 2);
padding-left: vw(13 * 2);
@include font_color("themeColor");
display: flex;
align-items: center;
height: 100%;
}
.el-checkbox__input {
display: inline-flex;
align-items: center;
justify-content: center;
&.is-checked {
.el-checkbox__inner {
background: url("~@/assets/img/checkedImg.png");
@include checkBox-style(vw(16 * 2));
border: vh(1 * 2) solid #007cdb;
}
+ .el-checkbox__label {
@include font_color("themeColor");
}
}
&.is-indeterminate {
.el-checkbox__inner {
background: url("~@/assets/img/checkedImg.png");
@include checkBox-style(vw(16 * 2));
border: vh(1 * 2) solid #007cdb;
}
}
&.is-disabled {
.el-checkbox__inner {
background: none;
background-color: rgba(192, 196, 204, 0.5);
@include checkBox-style(vw(16 * 2));
border: vh(1 * 2) solid #c0c4cc;
box-sizing: border-box;
}
}
.el-checkbox__inner {
background: url("~@/assets/img/noCheckImg.png");
@include checkBox-same-style(vw(16 * 2));
}
}
}
.column-label-another {
color: #797979;
}
}
}
.common-table-body {
flex: 1;
width: 100%;
&.common-table-body-min {
height: vh(262 * 2);
}
&.common-table-body-min-height {
height: min_vh(262 * 2) !important;
}
.common-table-body-wrapper {
height: fit-content;
padding-right: vw(36 * 2);
&.common-table-body-wrapper-no-padding {
padding-right: 0;
}
&.common-table-body-wrapper-min-padding {
padding-right: vw(20 * 2);
}
}
.common-table-row {
display: flex;
background: #fff;
margin-bottom: vh(20 * 2);
height: vh(100 * 2);
border-radius: vw(10 * 2);
position: relative;
box-sizing: border-box;
font-size: vw(18 * 2);
&.common-table-row-choose {
cursor: pointer;
}
&.row-border-green {
&:before {
width: vw(10 * 2);
height: 100%;
content: "";
@include background_color("alarmGreenBgColor");
border-radius: vw(10 * 2) 0 0 vw(10 * 2);
position: absolute;
left: 0;
}
}
&.row-border-yellow {
&:before {
width: vw(10 * 2);
height: 100%;
content: "";
@include background_color("alarmYellowBgColor");
border-radius: vw(10 * 2) 0 0 vw(10 * 2);
position: absolute;
left: 0;
}
}
&.row-border-orange {
&:before {
width: vw(10 * 2);
height: 100%;
content: "";
@include background_color("alarmHappenBgColor");
border-radius: vw(10 * 2) 0 0 vw(10 * 2);
position: absolute;
left: 0;
}
}
&.row-border-red {
border-color: #ff4949 !important;
}
&.row-border-warning-red {
border: vh(2 * 2) solid #ff452f !important;
}
&.row-is-active {
border: vh(2 * 2) solid #71807b;
&:before {
width: vw(10 * 2);
height: 100%;
content: "";
background: #808c87;
border-radius: vw(10 * 2) 0 0 vw(10 * 2);
position: absolute;
left: 0;
}
}
&.common-table-row-min-height {
height: vh(50 * 2);
}
.button-flex-box {
height: 100%;
position: relative;
width: 100%;
border-left: none !important;
display: flex;
align-items: center;
box-sizing: border-box;
justify-content: flex-end;
&.button-flex-box-padding {
padding-right: 0;
&.button-flex-box-wrap {
// flex-wrap: wrap;
flex-direction: column;
align-items: flex-end;
}
}
&.button-flex-box-wrap {
// flex-wrap: wrap;
flex-direction: column;
align-items: flex-end;
.button-Box-height {
height: vh(32 * 2);
+ .button-Box-height {
margin-left: 0;
}
&:first-child {
margin-bottom: vh(10 * 2);
}
&:last-child {
margin-bottom: vh(0 * 2);
}
.el-button {
width: vw(82 * 2);
height: vh(32 * 2);
+ .el-button {
margin-left: vw(10 * 2);
}
}
}
}
&.button-flex-box-small {
align-items: center;
.button-Box-height {
height: vh(32 * 2);
+ .button-Box-height {
margin-left: 0;
}
.el-button {
width: vw(82 * 2);
height: vh(32 * 2);
+ .el-button {
margin-left: vw(10 * 2);
}
}
}
}
&.one {
.button-Box-height {
min-width: min_vw(112 * 2);
.el-upload {
margin: 0;
}
}
}
.el-button {
width: vw(112 * 2);
height: vh(42 * 2);
border-radius: vw(21 * 2);
font-size: vw(20 * 2);
border: none;
outline: none;
span {
height: vh(24 * 2);
display: inline-flex;
align-items: center;
}
&.el-button--primary {
@include background_color("confirmButtonBgColor");
}
&.el-button--info {
@include background_color("infobtnBgColor");
}
&.el-button--success {
@include background_color("confirmButtonBgColor");
}
&.el-button--danger {
@include background_color("dangerbtnBgColor");
}
+ .el-button {
margin-left: vw(20 * 2);
}
}
}
.button-Box {
height: vh(42 * 2);
display: flex;
justify-content: flex-end;
margin-bottom: 0;
+ .button-Box {
margin-left: vw(20 * 2);
&.file-button-box {
margin-left: vw(20 * 2);
.el-button {
margin-left: 0;
}
}
// .el-button {
// margin-left: vw(20 * 2);
// }
margin-bottom: 0;
}
&.button-Box-height {
height: vh(42 * 2);
.el-button {
height: vh(42 * 2);
width: vw(112 * 2);
padding: 0;
&.button-four {
width: vw(112 * 2);
}
}
}
.el-button {
flex-shrink: 0;
border: none;
}
}
.cell-box {
padding: vh(10 * 2) vw(20 * 2);
flex-shrink: 0;
&.cell-padding {
padding: vh(20 * 2) vw(20 * 2);
}
&.cell-padding-min {
padding-top: vh(13 * 2);
padding-bottom: vh(13 * 2);
}
&.cell-padding-no-top {
padding: vw(8 * 2) vw(20 * 2);
}
&.has-border {
position: relative;
&:before {
content: "";
width: vw(1 * 2);
height: vh(21 * 2);
position: absolute;
right: 0;
top: 0;
bottom: 0;
margin: auto;
@include background_color("borderColor");
}
}
&.word-center {
display: flex;
align-items: center;
justify-content: center;
}
&.word-center-left {
display: flex;
align-items: center;
}
&.word-center-right {
display: flex;
align-items: center;
span {
text-align: right;
}
}
&.button-center-right {
justify-content: flex-end;
}
&.chart-padding {
padding: vw(6 * 2) vw(20 * 2);
}
.row-label {
width: 100%;
div {
&.one-line {
font-size: vw(18 * 2);
@include text-overflow-two;
.none-label {
width: fit-content;
white-space: nowrap;
}
span {
@include text-overflow-two;
}
}
&.no-warp {
font-size: vw(16 * 2);
@include text-overflow;
span {
@include text-overflow;
width: 100%;
display: inline-block;
}
}
&.two-line {
font-size: vw(18 * 2);
margin-top: vh(10 * 2);
color: #797979;
height: vh(25*2);
@include text-overflow;
&.two-line-mt {
margin-top: vh(7 * 2);
}
&.two-line-mts {
margin-top: vh(5 * 2);
}
.none-label {
width: fit-content;
white-space: nowrap;
}
span {
width: 100%;
display: inline-block;
@include text-overflow;
}
}
&.word-bold {
font-family: "PingFangSC-Semibold";
}
&.word-red {
color: #ff452f;
}
&.word-blue {
color: #2b5ae8;
}
&.row-label-bg {
width: vw(45 * 2);
height: vh(20 * 2);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: vw(10 * 2);
&.row-label-green {
@include background_color("alarmMsgBgColor");
}
&.row-label-yellow {
@include background_color("alarmYellowBgColor");
}
&.row-label-orange {
@include background_color("alarmRedBgColor");
}
&.row-label-gray {
@include background_color("pageBoxBgColor");
}
}
&.word-bold {
font-family: "PingFangSC-Semibold";
}
&.progress-box {
width: 100%;
display: flex;
flex-direction: column;
display: flex;
flex-direction: column;
align-items: center;
.device-num {
width: 100%;
color: #000;
text-align: center;
font-size: vw(16 * 2);
margin-bottom: vh(6 * 2);
}
.progress {
width: vw(82 * 2);
height: vh(32 * 2);
position: relative;
border-radius: vw(21 * 2);
background: #b5c0bc;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
.progress-color {
position: absolute;
left: 0;
height: 100%;
top: 0;
background: #2b5ae8;
}
.val {
font-size: vw(18 * 2);
color: #ffffff;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: fit-content;
height: fit-content;
}
}
}
&.common-progress-box {
display: flex;
align-items: center;
justify-content: center;
height: vh(50*2);
background: #EEF0EF;
border-radius: vw(5*2);
position: relative;
overflow: hidden;
.progress-bg-color {
position: absolute;
left: 0;
height: 100%;
top: 0;
background: #B5C0BC;
}
.val {
font-size: vw(18 * 2);
color: #000;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: fit-content;
height: fit-content;
}
}
img {
width: vw(22 * 2);
height: vw(22 * 2);
object-fit: contain;
display: block;
}
}
.el-checkbox {
width: fit-content;
padding: 0 vw(20 * 2);
display: inline-flex;
align-items: center;
height: 100%;
font-size: vw(12 * 2);
margin-right: 0;
.el-checkbox__label {
font-size: vw(12 * 2);
padding-left: vw(13 * 2);
@include font_color("themeColor");
display: flex;
align-items: center;
height: 100%;
}
.el-checkbox__input {
display: inline-flex;
align-items: center;
justify-content: center;
&.is-checked {
.el-checkbox__inner {
background: url("~@/assets/img/checkedImg.png");
@include checkBox-style(vw(16 * 2));
border: vh(1 * 2) solid #007cdb;
}
+ .el-checkbox__label {
@include font_color("themeColor");
}
}
&.is-indeterminate {
.el-checkbox__inner {
background: url("~@/assets/img/checkedImg.png");
@include checkBox-style(vw(16 * 2));
border: vh(1 * 2) solid #007cdb;
}
}
&.is-disabled {
.el-checkbox__inner {
background: none;
background-color: rgba(192, 196, 204, 0.5);
@include checkBox-style(vw(16 * 2));
border: vh(1 * 2) solid #c0c4cc;
}
}
.el-checkbox__inner {
background: url("~@/assets/img/noCheckImg.png");
@include checkBox-same-style(vw(16 * 2));
}
}
}
&.row-label-date {
width: 100%;
height: vh(36 * 2);
border-radius: vw(21 * 2);
border: vh(1 * 2) solid #797979;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: vw(18 * 2);
color: #797979;
}
.row-label-color {
color: #797979;
}
.row-label-color-default {
color: #000000 !important;
}
.word-font-default {
font-size: vw(18*2) !important;
}
.row-label-num-style {
width: vw(80 * 2);
height: vh(36 * 2);
background: #808c87;
border-radius: vw(21 * 2);
display: inline-flex !important;
align-items: center;
justify-content: center;
font-size: vw(24 * 2) !important;
color: #fff;
&-bg {
background: #ff452f;
}
}
.row-label-circle {
width: vw(60 * 2);
height: vw(60 * 2);
background: #808c87;
border-radius: 50%;
color: #fff;
display: inline-flex !important;
align-items: center;
justify-content: center;
font-size: vw(16 * 2) !important;
}
}
.table-chart {
@include background_color("pageBoxBgColor");
width: 100% !important;
height: vh(40 * 2) !important;
padding: 0 vw(15 * 2);
border-radius: vw(10 * 2);
section {
position: absolute !important;
.loading {
display: flex;
align-items: center;
justify-content: center;
}
.desc {
display: none;
}
}
}
.echarts-top {
position: absolute !important;
@include background_color("pageBoxBgColor");
width: 100% !important;
height: vh(40 * 2) !important;
padding: 0 vw(15 * 2);
border-radius: vw(10 * 2);
z-index: 99;
section {
position: absolute !important;
.loading {
display: flex;
align-items: center;
justify-content: center;
}
.desc {
display: none;
}
}
}
.el-badge {
width: 100%;
position: relative;
.el-badge__content {
position: absolute;
width: vw(17 * 2);
height: vw(17 * 2);
border-radius: 50%;
background-color: #ff452f;
top: vw(-17 * 2);
right: 0;
transform: none;
font-size: vw(12 * 2);
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
}
.common-table-box-fixed {
position: absolute;
right: vw(36 * 2);
top: 0;
z-index: 100;
height: vh(830 * 2);
padding-bottom: vh(6 * 2);
.common-table-fixed-header {
height: vh(17 * 2);
display: flex;
margin-bottom: vh(10 * 2);
align-items: center;
justify-content: flex-end;
padding-right: vw(50 * 2);
@include background_color("pageBoxBgColor");
font-family: "PingFangSC-Semibold";
}
.common-table-fixed-box {
height: vh(800 * 2);
overflow-x: hidden;
overflow-y: auto;
border-radius: 0 vw(10 * 2) vw(10 * 2) 0;
// @include background_color('bottomBoxBgColor');
&::-webkit-scrollbar {
display: none;
}
}
.common-table-fixed-wrapper {
height: fit-content;
.common-table-fixed-header-body {
padding-top: 0;
height: vh(55 * 2);
position: relative;
padding-right: vw(40 * 2);
margin-bottom: vh(10 * 2);
@include background_color("bottomBoxBgColor");
@include border_style("borderColor");
border-left: none !important;
border-radius: 0 vw(10 * 2) vw(10 * 2) 0;
display: flex;
align-items: center;
box-sizing: border-box;
justify-content: flex-end;
&.common-table-fixed-row-choose {
cursor: pointer;
}
&.fixed-is-active {
@include background-color("confirmButtonBgColor");
@include border_style("confirmButtonBgColor");
.button-Box {
.el-button {
@include border_style("borderColor");
border-color: #fff !important;
}
}
}
// .spance-bg {
// width: 100%;
// height: vh(10*2);
// // @include background_color('pageBoxBgColor');
// }
.button-Box {
height: vh(20 * 2);
display: flex;
justify-content: flex-end;
margin-bottom: 0;
+ .button-Box {
&.file-button-box {
margin-left: vw(10 * 2);
.el-button {
margin-left: 0;
}
}
.el-button {
margin-left: vw(10 * 2);
}
margin-bottom: 0;
}
&.button-Box-height {
height: vh(24 * 2);
.el-button {
height: vh(24 * 2);
width: vw(45 * 2);
padding: 0;
&.button-four {
width: vw(70 * 2);
}
}
}
.el-button {
border: none;
}
}
&:before {
display: none;
content: "";
width: vw(1 * 2);
height: vh(21 * 2);
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
@include background_color("borderColor");
}
}
}
}
}
- 上述样式单位如果想改为px
- 可以将vw(162) 、vh(162)这种的改为16px;
- 如果觉得改vw vh很麻烦可以使用下列函数放入你的文件中
@function vw($px) {
// 进行计算操作
$result: ($px / 2);
$factor: 100000;
$roundedValue: round($result * $factor);
$roundedResult: $roundedValue / $factor;
@return #{$result}px;
}
@function vh($px) {
$result: ($px / 2);
$factor: 100000;
$roundedValue: round($result * $factor);
$roundedResult: $roundedValue / $factor;
@return #{$result}px;
}
- 使用vw和vh 我这边是统一将宽高都设备2倍,然后页面整体缩放了
- 页面缩放:详见该篇文章vue 响应式transform
//默认设计稿的宽度
$designWidth: 3840;
//默认设计稿的高度
$designHeight: 2160;
//px转为vw的函数
@function vw($px) {
// 进行计算操作
$result: ($px / $designWidth * 2) * 100;
$factor: 100000;
$roundedValue: round($result * $factor);
$roundedResult: $roundedValue / $factor;
@return #{$roundedResult}vw;
}
//px转为vh的函数
@function vh($px) {
$result: ($px / $designHeight * 2) * 100;
$factor: 100000;
$roundedValue: round($result * $factor);
$roundedResult: $roundedValue / $factor;
@return #{$roundedResult}vh;
}
index.scss具体引用:详见该篇文章Vue项目切换主题颜色(mixin + scss)
vue文件引用table组件
<template>
<div class="page-container">
<h-common-table
:data="tableData"
:columns="tableColumns"
ref="myTable"
></h-common-table>
</div>
</template>
<script>
import HCommonTable from '@/components/commonTable/index'
export default {
mixins: [commonSearchMixin, tableMixins, loadingMixins],
components: {
HCommonTable
},
data() {
return {
tableData: [],
tableColumns: [],
typeList:[{
name:'类型11',
id: 1
},{
name:'类型2',
id: 2
}]
};
},
methods:{
valueSourceFormat(row) {
let item = this.typeList.find(el=>el.id==row.type)
rerurn item ? item.name: ''
},
valueAddressFormat(row) {
return row.dirct + row.address
}
}
mounted() {
this.tableColumns = [
{
label: "序号",
value: "sort",
width: this.windowWidth <= 1024 ? 70 * 2 : 78 * 2,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
isSort: true,
position: "center"
},
{
label: "创建日期",
value: "createTime",
isDate: true,
width: this.windowWidth <= 1024 ? 140 * 2 : 148 * 2,
position1: "center-left",
paddingLeft: 0,
paddingRight: 0,
isHidden: this.windowWidth <= 1024
},
{
label: "类型",
value: "type",
width: this.windowWidth <= 1024 ? 85 * 2 : 107 * 2,
position: "center",
valueFormatter: this.valueSourceFormat,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2
},
{
label: "名称",
value: "name",
wordColor: true,
isTooltip: true,
width: this.windowWidth <= 1024 ? 150 * 2 : 340 * 2,
position1: "center-left",
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2
},
{
label: "所在地",
value: "companyDistrictId",
isTooltip: true,
width: this.windowWidth <= 1024 ? 130 * 2 : 162 * 2,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
position1: "center-left",
valueFormatter: this.valueAddressFormat
},
{
label: "联系人/",
label2: "电话",
value: "contactName",
value1: "contactPhone",
width: this.windowWidth <= 1024 ? 145 * 2 : 190 * 2,
position1: "center-left",
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2
},
{
label: "操作",
isButton: true,
position: "center",
position1: "center",
wrap: true,
width: this.windowWidth <= 1024 ? 155 * 2 : 214 * 2,
value: "",
isSmall: this.windowWidth <= 1024 ? true : false,
paddingLeft: this.windowWidth <= 1024 ? 0 : 18 * 2,
buttonList: [
[
{
caption: "删除",
callback: this.deleteInfo,
type: "danger",
display: this.commonFunc.hasPermission("dealer-delete")
},
{
caption: "详情",
callback: this.lookInfo,
type: "success",
display: this.commonFunc.hasPermission("dealer-info")
}
],
[
{
caption: "编辑",
callback: this.changeInfo,
type: "success",
display: this.commonFunc.hasPermission("dealer-update")
}
]
]
}
];
}
beforeDestroy() {}
};
</script>
<style lang="scss" scoped></style>
文章来源:https://blog.csdn.net/weixin_46328739/article/details/135135533
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!