vue的table表格組件的封裝方式
vue table表格組件的封裝
封裝的vue表格組件,整理記錄下
1,分為兩個(gè)組件去封裝,一個(gè)是基本的表格的框架組件,一個(gè)是行內(nèi)容組件
基本的表格框架組件:
增加了移動(dòng)調(diào)整列大小功能
<template> ? <div class="data-table"> ? ? <!-- 表格標(biāo)題 --> ? ? <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"> ? ? ? <!-- 表格數(shù)據(jù)內(nèi)容 --> ? ? ? <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> ? ? ? <!-- 暫無(wú)數(shù)據(jù) --> ? ? ? <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: { ? ? ? //表格數(shù)據(jù) ? ? ? type: Array, ? ? ? default: () => [], ? ? }, ? ? isLoading: { ? ? ? //是否正在加載數(shù)據(jù) ? ? ? 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: { ? ? ? //多選表格,選中的數(shù)據(jù)項(xiàng)索引數(shù)組 ? ? ? deep: true, ? ? ? handler() { ? ? ? ? if (!this.isLoad) { ? ? ? ? ? this.$emit("update:selects", this.selectList); ? ? ? ? ? this.$emit("table-select", this.selectList); ? ? ? ? } ? ? ? }, ? ? }, ? ? selects() { ? ? ? //多選表格,選中的數(shù)據(jù)項(xiàng) ? ? ? 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() { ? ? ? //表格數(shù)據(jù)更新,重新渲染 ? ? ? 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() { ? ? ? //初始每列的寬度,保留每次調(diào)整后的列寬 ? ? ? 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; ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? }, ? ? //移動(dòng)調(diào)整列大小 ? ? 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>
行內(nèi)容組件:
<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); //數(shù)據(jù)表格組件 ? ? Vue.component("data-table-row", DataTableRow); //數(shù)據(jù)表格行組件 ? }, });
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是否顯示行的序號(hào),is-check是否可以選中,select.sync是選中的行數(shù)的序號(hào)
vue封裝table組件---萬(wàn)能表格
組件table.js
先看效果圖
搜索條件-按鈕都有的哦!拿來(lái)即用,不用謝,哈哈
<!-- 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> <!--擴(kuò)展dom--> <template v-else> <Table :key="`cus${index}`" :render="value.render" :param="scope" /> </template> </template> </el-table-column> </el-table> <!--分頁(yè)插件--> <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函數(shù) 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表格沒(méi)有被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: () => {} }, // 響應(yīng)式 searchFit: { type: Object, default: () => { return { xs: 24, sm: 12, md: 6, lg: 4 } } }, // 分頁(yè) pagination: { type: [Boolean, Object], default: false }, // 表格配置項(xiàng) tableConfig: { type: Object, default: () => {} }, extendSearchFields: { type: Array, default: () => [] }, // 快速跳轉(zhuǎn)至某一頁(yè) 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 }, // 分頁(yè)配置 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 }, // 聯(lián)合搜索的字段 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 }, // 搜索框的數(shù)量 searchLength() { return Object.keys(this.slotList).length + this.searchFields.length } }, watch: { // 監(jiān)聽(tīng) 分頁(yè)變化 page() { this.$emit('on-change', this.emitDataHandle()) }, // 監(jiān)聽(tīng) 配置項(xiàng)變化 extendSearchFields() { this.initialize() } }, created() { this.initialize() }, mounted() { this.$emit('on-table-mounted', this.$refs.table) }, methods: { // 事件觸發(fā)器 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 對(duì)象 * @description * * 處理對(duì)象參數(shù)值,排除對(duì)象參數(shù)值為”“、null、undefined,并返回一個(gè)新對(duì)象 */ 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>
父組件應(yīng)用文件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>
表頭參數(shù)culumns看這里:
舉個(gè)栗子 // 表頭 columns: [ { title: '序號(hào)', type: 'index', minWidth: 30, tooltip: true }, { title: '目標(biāo)類型', 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>本體庫(kù)</span> } else if (params.row.ontoClassify === 2) { return <span>項(xiàng)目庫(kù)</span> } } }, { title: '對(duì)應(yīng)本體', key: 'ontoName', minWidth: 100, tooltip: true }, { title: '任務(wù)名稱', key: 'instanceName', minWidth: 100, tooltip: true }, { title: '來(lái)源類型', key: 'instanceSource', minWidth: 70, tooltip: true, render: (h, params) => { return <span>{params.row.instanceSource === 1 ? '業(yè)務(wù)模型層' : '文件上傳'}</span> } }, { title: '源類型', key: 'originType', minWidth: 50, tooltip: true, render: (h, params) => { return <span>{params.row.instanceSource === 1 ? 'MySQL' : 'JSON'}</span> } }, { title: '狀態(tài)', key: 'instanceState', minWidth: 50, tooltip: true, render: (h, params) => { // instanceState=0失敗 instanceState=1成功 instanceState=2執(zhí)行中 instanceState=3暫停 instanceState=4停止 instanceState=5設(shè)置中 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> 執(zhí)行中 </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> 設(shè)置中 </span> ) } } }, { title: '創(chuàng)建時(shí)間', key: 'createdTime', minWidth: 120, tooltip: true, render: (h, params) => { // 日期格式化 return <span>{dateFormat(params.row.createdTime)}</span> } }, { title: '開(kāi)始時(shí)間', key: 'startTime', minWidth: 120, tooltip: true, render: (h, params) => { // 日期格式化 return ( <span> {params.row.startTime === '' || params.row.startTime === null ? '一 一' : dateFormat(params.row.startTime)} </span> ) } }, { title: '結(jié)束時(shí)間', 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> 繼續(xù)設(shè)置 </el-button>, <el-button // 狀態(tài)成功源類型是MySQL時(shí)顯示數(shù)據(jù)更新按鈕 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> 數(shù)據(jù)更新 </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> 啟動(dòng) </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> } } ],
因?yàn)橛衦ender參數(shù),所以組件需引入table.js,代碼如下:
// table.js export default { props: { render: { type: Function }, param: { type: Object } }, render(h) { return this.render(h, this.param) } }
效果圖看這里:
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決在vue項(xiàng)目中webpack打包后字體不生效的問(wèn)題
今天小編就為大家分享一篇解決在vue項(xiàng)目中webpack打包后字體不生效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09詳解vue-router數(shù)據(jù)加載與緩存使用總結(jié)
這篇文章主要介紹了詳解vue-router數(shù)據(jù)加載與緩存使用總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10vue+flask實(shí)現(xiàn)視頻合成功能(拖拽上傳)
這篇文章主要介紹了vue+flask實(shí)現(xiàn)視頻合成功能(拖拽上傳),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03vue.js路由mode配置之去掉url上默認(rèn)的#方法
今天小編就為大家分享一篇vue.js路由mode配置之去掉url上默認(rèn)的#方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11vue實(shí)現(xiàn)桌面向網(wǎng)頁(yè)拖動(dòng)文件的示例代碼(可顯示圖片/音頻/視頻)
這篇文章主要介紹了vue實(shí)現(xiàn)桌面向網(wǎng)頁(yè)拖動(dòng)文件的示例代碼(可顯示圖片/音頻/視頻),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03關(guān)于ElementUI el-table 鼠標(biāo)滾動(dòng)失靈的問(wèn)題及解決辦法
這篇文章主要介紹了關(guān)于ElementUI el-table 鼠標(biāo)滾動(dòng)失靈的問(wèn)題及解決辦法,本文給大家分享問(wèn)題所在原因及解決方案,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Vue如何實(shí)現(xiàn)u-form多個(gè)form表單同時(shí)校驗(yàn)
在 Vue 項(xiàng)目中使用 UView UI 的 u-form 組件時(shí),多個(gè)表單同時(shí)校驗(yàn)的需求非常常見(jiàn),本文主要介紹了如何使用 u-form 組件實(shí)現(xiàn)多個(gè)表單同時(shí)校驗(yàn),需要的可以參考一下2025-01-01