vue的table表格组件的封装方式
作者:maxiaoxin1314
这篇文章主要介绍了vue的table表格组件的封装方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
vue table表格组件的封装
封装的vue表格组件,整理记录下
1,分为两个组件去封装,一个是基本的表格的框架组件,一个是行内容组件
基本的表格框架组件:
增加了移动调整列大小功能
<template>
<div class="data-table">
<!-- 表格标题 -->
<table>
<thead>
<tr ref="dataTableHead">
<th v-if="isCheck">
<input type="checkbox" class="text-input" v-model="isAll" />
</th>
<th v-if="isNum">{{ $t("common.num") }}</th>
<slot name="data-table-head"></slot>
<th></th>
</tr>
</thead>
</table>
<div class="table-content">
<!-- 表格数据内容 -->
<table v-show="tableData.length > 0 && !isLoading">
<tbody ref="dataTableContent">
<slot name="data-table-content"></slot>
<!-- <data-table-row :idx="idx" :item="item" v-for="(item, idx) in tableData" :key="idx"></data-table-row> -->
</tbody>
</table>
<!-- 暂无数据 -->
<div class="table-nodata" v-show="tableData.length == 0 && !isLoading">{{ $t("common.nodata") }}</div>
<div class="table-loading" v-show="isLoading">{{ $t("common.loading") }}</div>
</div>
</div>
</template>
<script>
export default {
name: "DataTableComp",
props: {
tableData: {
//表格数据
type: Array,
default: () => [],
},
isLoading: {
//是否正在加载数据
type: Boolean,
default: false,
},
isCheck: {
type: Boolean,
default: false,
},
isNum: {
type: Boolean,
default: false,
},
selects: {
type: Array,
default: () => [],
},
},
provide() {
return { dataTable: this };
},
data: () => ({
isAll: false,
selectList: [],
isLoad: false,
}),
watch: {
selectList: {
//多选表格,选中的数据项索引数组
deep: true,
handler() {
if (!this.isLoad) {
this.$emit("update:selects", this.selectList);
this.$emit("table-select", this.selectList);
}
},
},
selects() {
//多选表格,选中的数据项
this.isLoad = true;
this.selectList = this.selects;
var that = this;
this.$nextTick(function() {
that.isLoad = false;
});
},
isAll() {
//是否全选多选表格
if (this.isAll) {
var list = [];
for (var i = 0; i < this.tableData.length; i++) {
list.push(i);
}
this.selectList = list;
} else {
this.selectList = [];
}
},
tableData() {
//表格数据更新,重新渲染
this.isLoad = true;
var that = this;
this.$nextTick(function() {
that.initColumWidth();
that.isLoad = false;
});
},
},
methods: {
clearSelect() {
//多选表格,清空选中
this.isAll = false;
},
listenEvent() {
this.app.$on("table-select-clear", this.clearSelect);
},
offEvent() {
this.app.$off("table-select-clear", this.clearSelect);
},
initColumWidth() {
//初始每列的宽度,保留每次调整后的列宽
if (this.$refs.dataTableContent && this.$refs.dataTableHead) {
if (this.tableData.length > 0 && !this.isLoading) {
var head = this.$refs.dataTableHead;
var body = this.$refs.dataTableContent;
if (body.children) {
for (var i = 0; i < body.children.length; i++) {
for (var j = 0; j < head.children.length - 1; j++) {
var td = body.children[i].children[j];
td.style.width = head.children[j].style.width;
}
}
}
}
}
},
//移动调整列大小
onTableColum() {
var movepage = document.getElementById("moving_page");
if (this.$refs.dataTableContent && this.$refs.dataTableHead) {
var dataTableContent = this.$refs.dataTableContent;
this.$refs.dataTableHead.onmousedown = function(e) {
if (e.target.tagName == "TH" && e.target != this.lastElementChild) {
var elmt = e.target;
var startX = e.pageX;
var distance = e.pageX - elmt.offsetLeft;
var leftRight = distance < elmt.offsetWidth * 0.5 ? "left" : "right";
var elmt1 = leftRight == "left" ? elmt.previousElementSibling : elmt.nextElementSibling;
if (elmt1 != this.lastElementChild) {
var width = elmt.offsetWidth;
var width1 = elmt1.offsetWidth;
movepage.style.display = "flex";
movepage.style.cursor = "ew-resize";
movepage.onmousemove = function(e) {
var w = e.pageX - startX + width;
var w1 = width + width1 - w;
elmt.style.width = w + "px";
elmt1.style.width = w1 + "px";
for (var i = 0; i < dataTableContent.children.length; i++) {
var td = dataTableContent.children[i].children[elmt.cellIndex];
var td1 = leftRight == "left" ? td.previousElementSibling : td.nextElementSibling;
td.style.width = w + "px";
td1.style.width = w1 + "px";
}
};
movepage.onmouseup = function() {
movepage.onmousemove = null;
movepage.style.display = "none";
};
}
}
e.preventDefault();
};
}
},
},
mounted() {
this.listenEvent();
this.onTableColum();
},
beforeDestroy() {
this.offEvent();
},
};
</script>
<style lang='scss'>
.data-table {
display: block;
overflow-x: hidden;
overflow-y: hidden;
padding-bottom: 0.1rem;
height: 100%;
width: 100%;
table {
background: white;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
thead > tr {
background: #cedeee;
border-radius: 0.4rem;
line-height: 3rem;
white-space: nowrap;
height: 3rem;
display: flex;
flex-direction: row;
cursor: ew-resize;
}
thead > tr > th {
text-align: center;
font-size: 1.4rem;
font-weight: normal;
}
thead > tr > th:not(:last-child) {
// border-right: solid 1px #0095ec;
min-width: 5rem;
}
thead > tr > th:last-child {
width: 0.8rem;
}
tbody > tr {
display: flex;
flex-direction: row;
border-radius: 0.4rem;
align-items: center;
line-height: 1.6rem;
min-height: 3rem;
}
tbody > tr:nth-child(even) {
background: #f3f3f3;
}
tbody > tr:hover,
tbody > tr.active {
color: #388dea;
background-color: #d9edf6;
}
tbody > tr.active {
font-weight: bold;
}
tbody > tr > td {
text-align: center;
font-size: 1.2rem;
min-width: 4rem;
word-break: break-word;
white-space: normal;
> span {
max-width: 100%;
white-space: normal;
word-break: break-word;
}
a {
color: #0095ec;
text-decoration: underline;
font-size: 1.2rem;
cursor: pointer;
}
button:nth-child(odd),
button.btn-white {
@extend .btn-white;
height: 2.4rem !important;
line-height: 2.4rem !important;
}
button:nth-child(even),
button.btn-orange {
@extend .btn-orange;
height: 2.4rem !important;
line-height: 2.4rem !important;
}
a:not(:last-child),
button:not(:last-child) {
margin-right: 0.8rem;
}
}
}
.table-content {
height: calc(100% - 3.1rem);
overflow-y: auto;
overflow-x: hidden;
border: dashed 0.1rem gainsboro;
border-top: none;
.table-nodata {
font-weight: bold;
margin: 0.8rem;
font-size: 1.2rem;
border: #e2a814 0.1rem dashed;
background-color: #f6f0ca;
display: flex;
align-items: center;
justify-content: center;
height: calc(100% - 1.8rem);
color: black;
}
.table-loading {
@extend .table-nodata;
color: red;
font-size: 1.4rem;
}
}
}
</style>行内容组件:
<template>
<tr>
<td v-if="dataTable.isCheck">
<input type="checkbox" class="text-input" v-model="dataTable.selectList" :value="idx" />
</td>
<td v-if="dataTable.isNum">{{idx+1}}</td>
<slot />
</tr>
</template>
<script>
export default {
name: "DataTableRow",
props: {
idx: {
type: Number,
default: 0
},
item: {
type: Object,
default: () => { }
}
},
inject: ["dataTable"],
provide () {
return { dataTableRow: this };
}
};
</script>
<style>
</style>2,main.js中全局定义使用:
import DataTableComp from "@/components/comp/table/DataTableComp";
import DataTableRow from "@/components/comp/table/DataTableRow";
Vue.use({
install: function() {
Vue.component("data-table", DataTableComp); //数据表格组件
Vue.component("data-table-row", DataTableRow); //数据表格行组件
},
});3,在组件中使用
<data-table :is-num="false" :table-data="dataList" :is-check="true" :is-custom="true" :selects.sync="selectList">
<template slot="data-table-head">
<th style="width:15rem">{{ $t("common.name") }}</th>
<th style="width:12rem">{{ $t("common.age") }}</th>
<th style="width:12rem">{{ $t("common.company") }}</th>
</template>
<template slot="data-table-content">
<data-table-row v-for="(item, idx) in dataList" :key="'abc' + idx" :idx="idx" :item="item">
<td style="width:15rem">{{ item.name}}</td>
<td style="width:12rem">{{ item.age}}</td>
<td style="width:12rem">{{ item.company}}</td>
</data-table-row>
</template>
</data-table>is-num是否显示行的序号,is-check是否可以选中,select.sync是选中的行数的序号
vue封装table组件---万能表格
组件table.js
先看效果图

搜索条件-按钮都有的哦!拿来即用,不用谢,哈哈

<!-- pro-table.vue -->
<template>
<div class="new-table">
<!-- 搜索框 -->
<div v-if="searchLength > 0" :class="tableType === '2' ? 'input-boxs' : 'input-boxs2'">
<div style="display: flex;justify-content: space-between;flex-wrap: wrap;">
<div class="ycl custom-row">
<div v-for="(slot, index) in slotList" :key="`custom-search-${index}`" class="col-pd" v-bind="searchFit">
<slot :name="index" />
</div>
<div v-for="field in searchFields" :key="field.key" v-bind="searchFit" class="col-pd">
<el-input
v-if="field.type === 'Input'"
:key="field.key"
v-model="search[field.key]"
v-bind="field.props"
:clearable="searchLength < 2"
@clear="initializeParams"
/>
<el-select
v-else-if="field.type === 'Select'"
:key="field.key + 1"
v-model="search[field.key]"
style="width: 100%;margin-bottom: 5px;"
v-bind="field.props"
>
<el-option
v-for="option in field.options"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
<el-datePicker
v-else-if="field.type === 'Date'"
:key="field.key + 2"
v-model="search[field.key]"
:type="field.dateType || 'date'"
v-bind="field.props"
style="display: block"
/>
<el-cascader
v-else-if="field.type === 'Cascader'"
v-model="search[field.key]"
v-bind="field.props"
:data="field.options"
/>
</div>
<div class="col-pd">
<!-- 搜索重置按钮 -->
<el-button type="primary" style="margin-right: 8px" @click="searchHandle">查询</el-button>
<el-button v-if="searchLength > 1" type="primary" plain @click="initializeParams">重置</el-button>
</div>
</div>
<div v-if="Object.keys(buttonList).length > 0" class="ycr custom-row">
<slot v-if="Object.keys(buttonList).length > 0" />
</div>
</div>
</div>
<!-- 按钮 -->
<div :class="tableType === '2' ? 'table-content-boxs' : 'table-content-boxs2'">
<el-table
ref="table"
class="iview-table"
style="width: 100%;"
:height="height"
:data="rows"
:span-method="spanMethod"
v-bind="tableProps"
@sort-change="(column, key, order) => emitEventHandler('on-sort-change', column, key, order)"
@selection-change="selection => emitEventHandler('on-selection-change', selection)"
@select-all-cancel="selection => emitEventHandler('on-select-all-cancel', selection)"
@select-all="selection => emitEventHandler('on-select-all', selection)"
@select-cancel="(selection, row) => emitEventHandler('on-select-cancel', selection, row)"
@select="(selection, row) => emitEventHandler('on-select', selection, row)"
@current-change="
(currentRow, oldCurrentRow) =>
(tableConfig['highlight-row'] || tableConfig['highlightRow']) &&
emitEventHandler('on-current-change', currentRow, oldCurrentRow)
"
>
<!--表格第一列-->
<el-table-column
v-if="columns.length>0 && columns[0].type"
:label="columns[0].title"
:type="columns[0].type"
:width="columns[0].width"
:min-width="columns[0].minWidth"
/>
<!--表格其它列-->
<el-table-column
v-for="(value,index) in columnAll"
:key="index"
:prop="value.key"
:label="value.title"
:min-width="value.minWidth"
:width="value.width"
show-overflow-tooltip
>
<template slot-scope="scope">
<template v-if="!value.render">
<template v-if="value.formatter">
{{ value.formatter(scope.row, value) }}
</template>
<template v-else-if="value.getImgurl">
<el-image
:src="value.getImgurl(scope.row, value)"
style="width: 70px; height: 70px"
:preview-src-list="value.previewSrcList ? value.previewSrcList(scope.row, value) : value.getImgurl(scope.row, value).split(',')"
/>
</template>
<template v-else>
{{ scope.row[value.key] }}
</template>
</template>
<!--扩展dom-->
<template v-else>
<Table :key="`cus${index}`" :render="value.render" :param="scope" />
</template>
</template>
</el-table-column>
</el-table>
<!--分页插件-->
<div v-show="rows.length" class="page">
<el-pagination
v-if="pagination"
:current-page="pageNumber"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="pageSize => (page = { pageNumber: 1, pageSize })"
@current-change="pageNumber => (page = emitDataHandle({ pageNumber }))"
/>
</div>
</div>
</div>
</template>
<script>
// render函数
import Table from './components/table'
export default {
name: 'NTable',
components: { Table },
props: {
tableType: {
type: String,
default: '1' // 1: has-card (table表格被card包裹) 2:no-card (table表格没有被table包裹)
},
columns: {
type: [Array, Object],
required: true
},
data: {
type: [Array, Object],
required: true
},
rowsField: {
type: String,
default: 'records'
},
width: {
type: String || Number,
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
},
totalField: {
type: String,
default: 'total'
},
pageNumberField: {
type: String,
default: 'current'
},
spanMethod: {
type: Object,
default: () => {}
},
// 响应式
searchFit: {
type: Object,
default: () => {
return {
xs: 24,
sm: 12,
md: 6,
lg: 4
}
}
},
// 分页
pagination: {
type: [Boolean, Object],
default: false
},
// 表格配置项
tableConfig: {
type: Object,
default: () => {}
},
extendSearchFields: {
type: Array,
default: () => []
},
// 快速跳转至某一页
showElevator: {
type: Boolean,
default: false
}
},
data () {
return {
page: {
pageNumber: 1,
pageSize: 10
},
search: {},
searchFields: [],
slotsList: [],
isFullscreen: false
}
},
computed: {
rows() {
return this.data[this.rowsField] || []
},
columnAll () {
const arr = []
this.columns.map(item => {
if (!item.type) {
arr.push(item)
}
})
return arr
},
total() {
return this.data[this.totalField] || 0
},
pageTotal() {
return this.data.pages || 0
},
pageNumber() {
return this.data[this.pageNumberField] || this.page.pageNumber || 1
},
pageSize() {
return this.page.pageSize || 10
},
// 表格配置
tableProps() {
const defatult = {
stripe: true
}
return this.tableConfig && this.isObject(this.tableConfig) && Object.keys(this.tableConfig).length
? { ...defatult, ...this.tableConfig }
: defatult
},
// 分页配置
pageProps() {
const defatult = {
// size: 'small',
showTotal: false,
showElevator: false,
showSizer: true
}
return this.pagination && this.isObject(this.pagination) && Object.keys(this.pagination).length
? { ...defatult, ...this.pagination }
: defatult
},
// 联合搜索的字段
isShowSelectInput() {
// eslint-disable-next-line no-irregular-whitespace
return this.columns.some(item => item.search && item.search.type === 'SelectInput') || false
},
slotList() {
const result = {}
for (const key in this.$slots) {
if (key.indexOf('custom-search') !== -1) {
result[key] = this.$slots[key]
}
}
return result
},
buttonList() {
const result = {}
for (const key in this.$slots) {
if (key.indexOf('default') !== -1) {
result[key] = this.$slots[key]
}
}
return result
},
// 搜索框的数量
searchLength() {
return Object.keys(this.slotList).length + this.searchFields.length
}
},
watch: {
// 监听 分页变化
page() {
this.$emit('on-change', this.emitDataHandle())
},
// 监听 配置项变化
extendSearchFields() {
this.initialize()
}
},
created() {
this.initialize()
},
mounted() {
this.$emit('on-table-mounted', this.$refs.table)
},
methods: {
// 事件触发器
emitEventHandler(event, ...args) {
this.$emit(event, ...args)
},
emitDataHandle(params = {}) {
return this.Object2NotNull({
...this.page,
...this.search,
...params
})
},
// 刷新表格
refresh() {
this.emitEventHandler('on-refresh', this.emitDataHandle())
},
resetParams() {
Object.keys(this.search).forEach(k => (this.search[k] = null))
return this.emitDataHandle({ pageNumber: 1, pageSize: 10 })
},
searchHandle() {
this.page.pageNumber = 1
this.emitEventHandler('on-search', this.emitDataHandle())
},
initializeParams() {
this.page.pageNumber = 1
Object.keys(this.search).forEach(k => (this.search[k] = null))
if (this.page.pageNumber === 1) {
this.$emit('on-reset', this.emitDataHandle({ pageNumber: 1, pageSize: 10 }))
}
},
isObject(value) {
const type = typeof value
return value != null && (type === 'object' || type === 'function')
},
/**
* @param {*} obj 对象
* @description *
* 处理对象参数值,排除对象参数值为”“、null、undefined,并返回一个新对象
*/
Object2NotNull(obj) {
const param = {}
if (obj === null || obj === undefined || obj === '') return param
for (var key in obj) {
if (Object.prototype.toString.call(obj[key]).slice(8, -1) === 'Object') {
param[key] = this.Object2NotNull(obj[key])
} else if (
obj[key] !== null &&
obj[key] !== undefined
// obj[key] !== ''
) {
param[key] = obj[key]
}
}
return param
},
getSearchFields() {
// return new Promise((resolve, reject) => {})
const temp = []
// 合并额外字段
const _columns = this.columns.filter(
// eslint-disable-next-line no-prototype-builtins
item => item.search && item.search.hasOwnProperty('type') && item.search.type !== 'SelectInput'
)
const searchFields = [..._columns, ...this.extendSearchFields]
searchFields.forEach(async (item, index) => {
const { search } = item
// eslint-disable-next-line no-prototype-builtins
if (search && search.hasOwnProperty('type')) {
const o = {
title: item.title,
key: item.key,
type: search.type,
sort: search.sort || index
}
// eslint-disable-next-line no-prototype-builtins
if (search.hasOwnProperty('props')) {
o.props = search.props
}
if (search.type === 'Select' || search.type === 'Cascader') {
let _options = null
if (Array.isArray(search.options)) {
_options = search.options
} else if (typeof search.options === 'function') {
const res = await search.options(...(search.params || []))
if (search.format && typeof search.format === 'function') {
_options = search.format.call(this, res)
} else {
_options = res
}
}
o.options = _options
}
if (search.type === 'Date') {
o.dateType = search.dateType
}
this.$set(this.search, item.key, search.type === 'Cascader' ? [] : null)
temp.push(o)
}
})
this.searchFields = temp.sort((a, b) => a.sort - b.sort)
},
initialize() {
// 获取需要查询的字段
this.getSearchFields()
// 初始化查询字段
// this.initializeParams()
}
}
}
</script>
<style lang="scss">
.new-table {
.custom-row {
display: flex;
flex-wrap: wrap;
// margin: 10px 0;
> button {
margin-right: 5px !important;
}
}
.custom-append {
display: flex;
> div :not(:last-child) {
// margin-right: 15px !important;
}
.custom-clild {
margin-right: 15px !important;
> div :not(:last-child) {
// margin-right: 5px !important;
margin-top: 1px;
}
}
}
.custom-search {
display: flex;
}
.page {
display: flex;
justify-content: flex-end;
align-items: center;
font-size: 13px;
font-family: Microsoft YaHei;
font-weight: 400;
color: rgba(144, 147, 153, 1);
margin-top: 20px;
}
.ycIpage {
.ivu-page-item-jump-next,
.ivu-page-item-jump-prev,
.ivu-page-next,
.ivu-page-item,
.ivu-page-prev {
border: none !important;
}
.ivu-page-item {
color: rgb(48, 49, 51);
font-weight: bold;
}
.ivu-page-item-active {
color: rgb(24, 144, 255);
}
}
.ivu-table-wrapper {
margin-bottom: 32px;
}
.ivu-table::before {
height: 0 !important;
}
.ivu-input-group-prepend,
.ivu-input-group-append {
background: #fff;
}
.ivu-input-group-append .ivu-btn {
i {
font-size: 16px;
position: relative;
right: 8px;
}
}
.no-data-text {
display: block;
margin-left: 10px;
font-size: 16px;
margin: 100px;
opacity: 0.8;
.iconfont {
font-size: 140px;
color: #e2e5eb;
}
}
.input-boxs {
padding: 12px 10px 12px 10px;
margin-bottom: 8px;
background-color: #fff;
border-radius: 2px;
}
.input-boxs2 {
margin-bottom: 14px;
// margin-top: 11px;
}
.table-content-boxs {
padding: 0 10px 6px;
background-color: #fff;
border-radius: 2px;
}
.table-content-boxs {
padding-top: 10px;
}
.table-content-boxs2 {
margin-top: 10px;
}
.iview-table {
margin-top: 10px;
}
.no-button-text {
font-size: 15px;
font-weight: 700;
}
.func-icon-btn {
font-size: 18px;
font-weight: bold;
margin-left: 5px;
}
.col-pd {
// padding: 0;
margin-right: 10px;
}
}
</style>
<style lang="scss" scoped>
::v-deep .el-row--flex {
margin-top: 0px !important;
height: 36px;
}
::v-deep .el-table::before{
height: 0 !important;
}
::v-deep .el-table td{
padding: 12px 0 !important;
height: 23px !important;
line-height: 23px !important;
}
.new-table {
margin-top: 0 !important;
.ycr{
height: 36px;
}
}
</style>父组件应用文件father.vue
代码如下:
<NTable
:columns="columns"
:data="tableList"
:height="'650'"
:pagination="pagination"
rows-field="records"
:table-type="'0'"
:table-config="{ stripe: false }"
:extend-search-fields="extendSearchFields"
@on-change="changeHandle"
@on-search="changeSearch"
@on-reset="resetSearch"
>
<el-button v-hasPermi="['noumenon:link:add']" type="primary" @click="openTask">{{ title }}</el-button>
</NTable>表头参数culumns看这里:
举个栗子
// 表头
columns: [
{
title: '序号',
type: 'index',
minWidth: 30,
tooltip: true
},
{
title: '目标类型',
key: 'ontoClassify',
minWidth: 60,
tooltip: true,
render: (h, params) => {
if (params.row.ontoClassify === 0) {
return <span>定制本体</span>
} else if (params.row.ontoClassify === 1) {
return <span>本体库</span>
} else if (params.row.ontoClassify === 2) {
return <span>项目库</span>
}
}
},
{
title: '对应本体',
key: 'ontoName',
minWidth: 100,
tooltip: true
},
{
title: '任务名称',
key: 'instanceName',
minWidth: 100,
tooltip: true
},
{
title: '来源类型',
key: 'instanceSource',
minWidth: 70,
tooltip: true,
render: (h, params) => {
return <span>{params.row.instanceSource === 1 ? '业务模型层' : '文件上传'}</span>
}
},
{
title: '源类型',
key: 'originType',
minWidth: 50,
tooltip: true,
render: (h, params) => {
return <span>{params.row.instanceSource === 1 ? 'MySQL' : 'JSON'}</span>
}
},
{
title: '状态',
key: 'instanceState',
minWidth: 50,
tooltip: true,
render: (h, params) => {
// instanceState=0失败 instanceState=1成功 instanceState=2执行中 instanceState=3暂停 instanceState=4停止 instanceState=5设置中
if (params.row.instanceState === 1) {
return (
<span>
<i
class='dotClass'
style='background-color: springgreen;width:8px; height:8px; border-radius: 50%; display: inline-block; margin-right:3px'
></i>
成功
</span>
)
} else if (params.row.instanceState === 0) {
return (
<span>
<i
class='dotClass'
style='background-color: red;width:8px; height:8px; border-radius: 50%; display: inline-block; margin-right:3px'
></i>
失败
</span>
)
} else if (params.row.instanceState === 2) {
return (
<span>
<i
class='dotClass'
style='background-color: blue;width:8px; height:8px; border-radius: 50%; display: inline-block; margin-right:3px'
></i>
执行中
</span>
)
} else if (params.row.instanceState === 3) {
return (
<span>
<i
class='dotClass'
style='background-color: yellow;width:8px; height:8px; border-radius: 50%; display: inline-block; margin-right:3px'
></i>
暂停
</span>
)
} else if (params.row.instanceState === 4) {
return (
<span>
<i
class='dotClass'
style='background-color: red;width:8px; height:8px; border-radius: 50%; display: inline-block; margin-right:3px'
></i>
停止
</span>
)
} else if (params.row.instanceState === 5) {
return (
<span>
<i
class='dotClass'
style='background-color: #1C7FFD;width:8px; height:8px; border-radius: 50%; display: inline-block; margin-right:3px'
></i>
设置中
</span>
)
}
}
},
{
title: '创建时间',
key: 'createdTime',
minWidth: 120,
tooltip: true,
render: (h, params) => {
// 日期格式化
return <span>{dateFormat(params.row.createdTime)}</span>
}
},
{
title: '开始时间',
key: 'startTime',
minWidth: 120,
tooltip: true,
render: (h, params) => {
// 日期格式化
return (
<span>
{params.row.startTime === '' || params.row.startTime === null
? '一 一'
: dateFormat(params.row.startTime)}
</span>
)
}
},
{
title: '结束时间',
key: 'endTime',
minWidth: 120,
tooltip: true,
render: (h, params) => {
// 日期格式化
return (
<span>
{params.row.endTime === '' || params.row.endTime === null ? '一 一' : dateFormat(params.row.endTime)}
</span>
)
}
},
{
title: '操作',
key: 'action',
width: 250,
render: (h, params) => {
const group = [
<el-button
type='text'
size='small'
onClick={() => {
this.showDetails = true
this.$nextTick(() => {
// this.$refs['instanceTaskDetails'].init(params.row.instanceSource)
this.$refs['instanceTaskDetails'].init(params)
})
// this.detail(params.row)
}}
>
详情
</el-button>,
<el-button
v-show={params.row.instanceState === 0}
type='text'
size='small'
onClick={() => {
this.editModel(params.row, 'edit')
}}
v-hasPermi={['noumenon:link:edite']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
重新编辑
</el-button>,
<el-button
v-show={params.row.instanceState === 5}
type='text'
size='small'
onClick={() => {
this.editModel(params.row)
}}
v-hasPermi={['noumenon:link:edite']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
继续设置
</el-button>,
<el-button
// 状态成功源类型是MySQL时显示数据更新按钮
v-show={params.row.instanceState === 1 && params.row.instanceSource === 1}
type='text'
size='small'
onClick={() => {
this.dataUpdate(params.row)
}}
v-hasPermi={['noumenon:link:update']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
数据更新
</el-button>,
<el-button
v-show={params.row.instanceState === 0}
type='text'
size='small'
onClick={() => {
this.showReason = true
this.$nextTick(() => {
this.$refs['ViewReason'].init(params.row.instanceId)
})
}}
v-hasPermi={['noumenon:link:findReason']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
查看原因
</el-button>,
<el-button
v-show={params.row.instanceState === 2}
type='text'
size='small'
onClick={() => {
this.suspend(params.row, 3)
}}
v-hasPermi={['noumenon:link:pause']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
暂停
</el-button>,
<el-button
v-show={params.row.instanceState === 2}
type='text'
size='small'
onClick={() => {
this.suspend(params.row, 4)
}}
v-hasPermi={['noumenon:link:end']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
终止
</el-button>,
<el-button
v-show={params.row.instanceState === 3 || params.row.instanceState === 4}
type='text'
size='small'
onClick={() => {
this.dataUpdate(params.row)
}}
v-hasPermi={['noumenon:link:start']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
启动
</el-button>,
<el-button
v-show={params.row.instanceState !== 2}
type='text'
size='small'
onClick={() => {
this.delList(params)
}}
v-hasPermi={['noumenon:link:delete']}
>
<span style='color:#eaeaea;margin-right:5px;height:10px;display:inline-block;line-height:10px'>|</span>
删除
</el-button>
]
return <div class='iview-action'>{group}</div>
}
}
],因为有render参数,所以组件需引入table.js,代码如下:
// table.js
export default {
props: {
render: {
type: Function
},
param: {
type: Object
}
},
render(h) {
return this.render(h, this.param)
}
}效果图看这里:

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
