123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- <template>
- <div class="table-page">
- <el-table
- :key="renderKey"
- ref="elTablet"
- :row-key="getRowKey"
- v-loading="options.loading"
- :data="dataSource"
- :max-height="options.maxHeight"
- :height="options.height"
- :stripe="options.stripe"
- :border="options.border"
- @select="handleSelect"
- @select-all="selectAll"
- @row-click="handleRowClick"
- @selection-change="handleSelectionChange"
- @current-change="handleCurrentChange"
- highlight-current-row
- default-expand-all
- :cell-style="cellStyle"
- :header-cell-style="{ color: '#515a6e', background: '#f5f5f5' }"
- :tree-props="options.treeProps"
- :row-style="{ cursor: options.cursor || '' }"
- >
- <!--selection选择框-->
- <el-table-column v-if="options.mutiSelect" type="selection" :reserve-selection="true" style="width: 50px" align="center"> </el-table-column>
- <!--序号-->
- <el-table-column v-if="options.index" label="序号" type="index" width="100" align="center"> </el-table-column>
- <!--数据列-->
- <template v-for="(column, index) in columns">
- <el-table-column :key="index" :prop="column.prop" :label="column.label" :align="column.align || 'center'" :width="column.width" :fixed="column.fixed" show-overflow-tooltip v-if="!column.isHidden">
- <template slot-scope="scope">
- <!-- 含有click函数 -->
- <template v-if="column.onClick && !column.edit">
- <span @click.stop="column.onClick(scope.row, scope.$index, scope)">{{ scope.row[column.prop] }}</span>
- </template>
- <!-- 带编辑功能列 -->
- <template v-else-if="column.edit">
- <!-- 编辑状态 -->
- <template v-if="scope.row[scope.column.property + 'isShow']">
- <el-input :ref="scope.column.property" @blur="handleEditBlur(column, scope)" v-model="scope.row[column.prop]"></el-input>
- </template>
- <!-- 非编辑状态 -->
- <template v-else>
- <span class="el-table-edit-text" @click="editCell(scope.row, scope.column)"><i class="el-icon-edit"></i>{{ scope.row[column.prop] }}</span>
- </template>
- </template>
- <!-- 含有render函数 -->
- <template v-else-if="column.render">
- <RenderDom :row="scope.row" :index="index" :render="column.render" />
- </template>
- <!-- 有img图片显示 -->
- <template v-else-if="column.img">
- <img v-if="scope.row[column.prop] && scope.row[column.prop].length > 0" :src="scope.row[column.prop][0]" class="w-img" alt="加载失败" />
- <img v-else :src="logo" class="w-img" alt="加载失败" />
- </template>
- <!-- 字典展示 -->
- <template v-else-if="column.dictData">
- <span>{{ scope.row[column.prop] | dictFind(dictData, column.dictData, column.dictLabel, column.dictValue) }}</span>
- </template>
- <!-- 没有render函数且没有图片要显示 -->
- <template v-else>
- <span>{{ scope.row[column.prop] }}</span>
- </template>
- <!-- button 操作按钮 btn.statusKey 判断启用的字段 | btn.disableKey 判断禁用的值 | disableKey在启用和禁用时相反-->
- <!-- 禁用分两种情况 一种是 disableKey disableKey 是指状态值是 disableKey 的时候禁用 -->
- <!-- 另一种是 unDisableKey unDisableKey 是指状态值不是 unDisableKey 的时候禁用 -->
- <!-- btn.isChildShow 控制子级是否显示,isParentShow控制父级是否显示 -->
- <!-- v-show="hasChildren(scope.row, btn.showType)" -->
- <template v-if="column.button">
- <template v-for="(btn, i) in column.group">
- <el-button
- v-show="hasChildren(scope.row, btn.showType)"
- v-if="btn.statusKey"
- :key="i"
- :type="btn.type"
- :round="btn.round"
- :size="btn.size || 'mini'"
- :icon="btn.icon"
- :plain="btn.plain"
- @click.stop="btn.onClick(scope.row, scope.$index, scope)"
- :disabled="unDisabled(scope.row[btn.statusKey], btn.unDisableKey, btn.disableKey)"
- >{{ btn.name }}</el-button
- >
- <el-button
- v-show="hasChildren(scope.row, btn.showType)"
- v-if="!btn.statusKey"
- :key="i"
- :type="btn.type"
- :round="btn.round"
- :size="btn.size || 'mini'"
- :icon="btn.icon"
- :plain="btn.plain"
- @click.stop="btn.onClick(scope.row, scope.$index, scope)"
- :disabled="btn.isDisabled"
- >{{ btn.name }}</el-button
- >
- </template>
- </template>
- <!-- slot 你可以其他常用项 -->
- </template>
- </el-table-column>
- </template>
- </el-table>
- <!-- 分页 -->
- <el-pagination
- v-if="pagination"
- background
- :total="pagination.total"
- :page-size="pagination.pageSize"
- :page-sizes="[10, 20, 30, 40, 50]"
- layout="sizes,total, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleIndexChange"
- style="padding: 20px; text-align: center"
- ></el-pagination>
- </div>
- </template>
- <script>
- import { deepClone } from '@/utils'
- export default {
- name: 'LTable',
- components: {
- RenderDom: {
- functional: true,
- props: {
- row: Object,
- render: Function,
- index: Number,
- column: {
- type: Object,
- default: null
- }
- },
- render: (h, data) => {
- const params = {
- row: data.props.row,
- index: data.props.index
- }
- if (data.props.column) params.column = data.props.column
- return data.props.render(h, params)
- }
- }
- },
- props: {
- dictData: Object, //字典对象
- dataSource: Array, // table内容数据
- options: Object, // 表格参数控制 maxHeight、stripe 等等...
- columns: Array, // 表头
- fetch: {
- type: Function,
- default: function () {}
- }, // 获取数据的函数
- pagination: Object, // 分页,不传则不显示
- typeTable: String,
- defaultFetch: {
- type: Boolean,
- default: true
- },
- RowKey: {
- type: String,
- default: 'id'
- }
- },
- computed: {
- unDisabled() {
- return function (val, unDisableKey, disableKey) {
- if (unDisableKey || unDisableKey === 0) {
- if (typeof unDisableKey == 'object') {
- return !unDisableKey.includes(Number(val))
- } else {
- return val != unDisableKey
- }
- }
- if (disableKey) {
- if (typeof disableKey == 'object') {
- return disableKey.includes(Number(val))
- } else {
- return val == disableKey
- }
- }
- }
- }
- },
- data() {
- return {
- oldCellData: null,
- renderKey: Math.random(),
- logo: require('@/assets/logo.png'),
- checkedKeys: false,
- editStatusMap: {}
- }
- },
- filters: {
- dictFind(v, dictData, dictName, dictLabel, dictValue) {
- const item = dictData[dictName].find((e) => e[dictValue] == v)
- return item ? item[dictLabel] : v
- }
- },
- created() {
- if (this.defaultFetch) {
- this.options.initTable && this.fetch()
- } else {
- this.options.initTable
- }
- },
- methods: {
- hasChildren(row, showType) {
- //父级显示
- if (showType && showType == '0') {
- //父级判断
- if (row.parentId == null || row.parentId == '') {
- return true
- } else {
- return false
- }
- }
- //子级显示
- else if (showType && showType == '1') {
- //父级判断
- if ((row.parentId == null || row.parentId == '') && row.children && row.children.length > 0) {
- return false
- } else {
- return true
- }
- } else {
- return true
- }
- },
- editCell(row, column) {
- this.oldCellData = deepClone(row)
- this.$set(row, column.property + 'isShow', true)
- this.$nextTick(() => {
- this.$refs[column.property][0] && this.$refs[column.property][0].focus()
- })
- },
- handleEditBlur(column, scope) {
- scope.row[scope.column.property + 'isShow'] = false
- column.onChange(scope, this.oldCellData)
- },
- // table 文本颜色
- cellStyle(row, column, rowIndex, columnIndex) {
- if (row.column.label == '当前状态' && row.row.status == 1) {
- return 'color:#0ED1AA'
- } else if (row.column.label == '当前状态' && row.row.status == 2) {
- return 'color:#F3384F'
- }
- },
- // pageSize 改变时触发事件
- handleSizeChange(size) {
- this.pagination.pageSize = size || 10
- this.fetch()
- },
- // currentPage 改变时触发事件
- handleIndexChange(current) {
- this.pagination.pageIndex = current
- this.fetch()
- },
- handleSelect(selectRows, targetRow) {
- // 选中
- if (this.isObjectInArray(targetRow, selectRows)) {
- this.select(targetRow.children || [], true)
- } else {
- if (targetRow.children && targetRow.children.length) {
- let newTargetRow = this.flattenArray(targetRow.children)
- // 两个都选中 1个选中1个未选择 两个都未选中
- if (newTargetRow.every((itemB) => selectRows.some((itemA) => this.isEqual(itemA, itemB)))) {
- this.select(targetRow.children, false)
- } else {
- this.select(targetRow.children, true)
- this.$refs.elTablet.toggleRowSelection(targetRow, true)
- }
- }
- }
- },
- // 多选框选择变化触发事件
- handleSelectionChange(selection) {
- this.$emit('selection-change', selection)
- },
- // 单选框
- handleCurrentChange(selection) {
- this.$emit('current-change', selection)
- },
- // 点击table某一行时触发事件
- handleRowClick(row, event, column) {
- this.$emit('handleRowClick', row, event, column)
- },
- // 翻页时,记住上一页的勾选标识
- getRowKey(row) {
- return this.options.treeProps ? (this.options.rowKey ? row[this.options.rowKey] : row.id || row.value || row.avmatCategoriesCode) : null
- },
- // 控制 table 子级 全选
- selectAll(selection) {
- this.checkedKeys = !this.checkedKeys
- this.select(this.dataSource, this.checkedKeys)
- this.$emit('select-all', selection)
- },
- toggleRowSelection(row, toggle) {
- this.$refs.elTablet.toggleRowSelection(row, toggle)
- },
- // 控制 table 子级 全选
- select(d, c) {
- d.forEach((row) => {
- this.$refs.elTablet.toggleRowSelection(row, c)
- if (row.children && row.children.length > 0) {
- this.select(row.children, c)
- }
- })
- },
- // 设定某一行为选中行
- setCurrentRow(row) {
- this.$refs.elTablet.setCurrentRow(row)
- },
- clearSelection() {
- this.checkedKeys = false
- this.$refs.elTablet.clearSelection()
- },
- isObjectInArray(obj, arr) {
- return arr.some((item) => {
- return Object.keys(obj).every((key) => {
- return obj[key] === item[key]
- })
- })
- },
- isEqual(objA, objB) {
- return JSON.stringify(objA) === JSON.stringify(objB)
- },
- flattenArray(arr) {
- return [].concat(...arr.map((item) => (Array.isArray(item.children) ? this.flattenArray(item.children) : item)))
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- @import './index.scss';
- </style>
|