670 lines
24 KiB
Vue
670 lines
24 KiB
Vue
<template>
|
||
<a-table
|
||
class="j-table"
|
||
ref="table"
|
||
:bordered="bordered"
|
||
:columns="resultColumns"
|
||
:components="components"
|
||
:scroll="scroll || selfScroll"
|
||
v-bind="$attrs"
|
||
v-on="$listeners">
|
||
|
||
<!-- 如果插槽是作用域插槽,将作用域插槽的props包装成对象传递给slot -->
|
||
<template v-for="(_, slotName) in $scopedSlots" :slot="slotName" slot-scope="text, record, index">
|
||
<slot :name="slotName" v-bind="{text, record, index}" />
|
||
</template>
|
||
<!-- 如果是普通插槽,直接使用$slots渲染 -->
|
||
<slot v-for="(_, slotName) in $slots" :name="slotName" :slot="slotName" />
|
||
|
||
<template slot="text" slot-scope="text">
|
||
<a-tooltip overlay-class-name="tooltip-style">
|
||
<template slot="title">{{ text || text === 0 ? text : global.emptyLine }}</template>
|
||
<div class="table-text">{{ text || text === 0 ? text : global.emptyLine }}</div>
|
||
</a-tooltip>
|
||
</template>
|
||
|
||
<!-- 操作栏 -->
|
||
<template slot="action" slot-scope="text, record, index">
|
||
<slot name="action" v-bind="{text, record, index}">
|
||
<div class="action-span-cell">
|
||
<!-- 传了operSpecialJudgeField,需要特殊判断操作列是否显示更多 -->
|
||
<template v-if="operSpecialJudgeField">
|
||
<template v-if="operSpecialJudge(record).length > operateMaxNum + 1">
|
||
<!-- 需要更多按钮 -->
|
||
<a @click="operationClick(operSpecialJudge(record)[0],record)">{{ operSpecialJudge(record)[0].text }}</a>
|
||
<template v-if="operSpecialJudge(record).length > operateMaxNum">
|
||
<a-divider type="vertical" />
|
||
<a-dropdown placement="bottomCenter">
|
||
<a-icon type="more" class="operate-icon-btn operate-icon-more" />
|
||
<a-menu slot="overlay">
|
||
<a-menu-item v-for="(operation, index) in operSpecialJudge(record).slice(operateMaxNum)" :key="index">
|
||
<a @click="operationClick(operation,record)">
|
||
<div class="operate-btn">
|
||
{{ operation.text }}
|
||
</div>
|
||
</a>
|
||
</a-menu-item>
|
||
</a-menu>
|
||
</a-dropdown>
|
||
</template>
|
||
</template>
|
||
<template v-else>
|
||
<!-- 不需要更多按钮 -->
|
||
<template v-for="(operation, index) in operSpecialJudge(record)">
|
||
<a :key="index" @click="operationClick(operation,record)">{{ operation.text }}</a>
|
||
<a-divider type="vertical" v-if="index !== operSpecialJudge(record).length - 1" />
|
||
</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>
|
||
<!-- 没有特殊判断,直接渲染operationList -->
|
||
<!-- 需要更多按钮的情况 -->
|
||
<template v-if="getLineOperationList(record).length > operateMaxNum + 1">
|
||
<a @click="operationClick(getLineOperationList(record)[0],record)">{{ getLineOperationList(record)[0].text }}</a>
|
||
<template v-if="getLineOperationList(record).length > operateMaxNum">
|
||
<a-divider type="vertical" />
|
||
<a-dropdown placement="bottomCenter">
|
||
<a-icon type="more" class="operate-icon-btn operate-icon-more" />
|
||
<a-menu slot="overlay">
|
||
<a-menu-item v-for="(operation, index) in getLineOperationList(record).slice(operateMaxNum)" :key="index">
|
||
<a @click="operationClick(operation,record)">
|
||
<div class="operate-btn">
|
||
{{ operation.text }}
|
||
</div>
|
||
</a>
|
||
</a-menu-item>
|
||
</a-menu>
|
||
</a-dropdown>
|
||
</template>
|
||
</template>
|
||
<template v-else-if="getLineOperationList(record).length > 0">
|
||
<template v-for="(operation, index) in getLineOperationList(record)">
|
||
<a :key="index" @click="operationClick(operation,record)">{{ operation.text }}</a>
|
||
<a-divider type="vertical" v-if="index !== getLineOperationList(record).length - 1" />
|
||
</template>
|
||
</template>
|
||
</template>
|
||
</div>
|
||
</slot>
|
||
</template>
|
||
|
||
<div slot="settingDropdown">
|
||
<a-card v-if="needSettingColumnHideOrFreeze">
|
||
<a-table
|
||
rowKey="key"
|
||
:style="settingStyle"
|
||
tableLayout="fixed"
|
||
size="small"
|
||
bordered
|
||
:pagination="false"
|
||
:scroll="settingScroll"
|
||
:data-source="settingDataSource"
|
||
:columns="settingColumns">
|
||
|
||
<a-checkbox slot="hide" slot-scope="text, record"
|
||
:checked="text"
|
||
:disabled="record.disabledHide"
|
||
@change="changeSetting(text, 'hide', record)"></a-checkbox>
|
||
<a-checkbox slot="freeze" slot-scope="text, record"
|
||
:checked="text"
|
||
:disabled="record.disabledFreeze"
|
||
@change="changeSetting(text, 'freeze', record)"></a-checkbox>
|
||
</a-table>
|
||
</a-card>
|
||
</div>
|
||
<a-icon ref="settingBtn" slot="settingIcon" type="setting" :style="{ fontSize:'16px', color: '#108ee9' }"
|
||
v-if="needSettingColumnHideOrFreeze" />
|
||
|
||
</a-table>
|
||
</template>
|
||
|
||
<script>
|
||
import '@assets/less/common.less'
|
||
import Vue from 'vue'
|
||
import { cloneDeep } from 'lodash'
|
||
import VueDraggableResizable from 'vue-draggable-resizable'
|
||
import { isHasPermission } from '@/utils/hasPermission'
|
||
|
||
Vue.component('vue-draggable-resizable', VueDraggableResizable)
|
||
|
||
const actionKey = 'action'
|
||
// 保存localStorage中的后缀
|
||
const saveSuffix = ':JTable'
|
||
// 拿到column的key
|
||
const getKey = col => col.key || col.dataIndex
|
||
// 所有JTable的缓存key
|
||
const J_TABLE_KEYS = 'J_TABLE_KEYS'
|
||
export default {
|
||
name: 'JTable',
|
||
props: {
|
||
// 用于持久化存储列配置,保证唯一
|
||
tableKey: {
|
||
type: String,
|
||
required: false,
|
||
default: 'j-table'
|
||
},
|
||
columns: {
|
||
type: Array,
|
||
required: true
|
||
},
|
||
// 配置表的样式
|
||
settingStyle: {
|
||
type: Object,
|
||
required: false,
|
||
default: () => ({ width: '300px' })
|
||
},
|
||
// 配置表的scroll
|
||
settingScroll: {
|
||
type: Object,
|
||
required: false,
|
||
default: () => ({ y: 300 })
|
||
},
|
||
// 如果需要拖拽后增加总列宽而不是占用其他列宽度:需要父组件 :scroll.sync="scroll"
|
||
scroll: {
|
||
type: Object,
|
||
required: false
|
||
},
|
||
// 列最小宽度
|
||
columnMinWidth: {
|
||
type: Number,
|
||
required: false,
|
||
default: 100
|
||
},
|
||
bordered: {
|
||
type: Boolean,
|
||
required: false
|
||
},
|
||
// 是否需要设置冻结列和显隐列
|
||
needSettingColumnHideOrFreeze: {
|
||
type: Boolean,
|
||
required: false,
|
||
default: false
|
||
},
|
||
// 是否需要将冻结和显隐的设置存储在localStorage中
|
||
needSaveSettingInLocal: {
|
||
type: Boolean,
|
||
required: false,
|
||
default: false
|
||
},
|
||
// 是否可拖拽
|
||
canDrag: {
|
||
type: Boolean,
|
||
required: false,
|
||
default: false
|
||
},
|
||
// 操作列数据
|
||
operationList: {
|
||
type: Array,
|
||
required: false,
|
||
default: () => {
|
||
return []
|
||
}
|
||
},
|
||
// 操作列显示更多前的最大个数
|
||
operateMaxNum: {
|
||
type: Number,
|
||
required: false,
|
||
default: 1
|
||
},
|
||
// 操作列对于哪个字段有特殊判断
|
||
operSpecialJudgeField: {
|
||
type: String,
|
||
required: false,
|
||
default: ''
|
||
},
|
||
// 操作列需要特殊判断的字段是哪些值时,过滤不符合条件按钮
|
||
operSpecialJudgeValue: {
|
||
type: [Array, String, Boolean],
|
||
required: false,
|
||
default: true
|
||
},
|
||
// 操作列特殊判断时需要删掉的按钮
|
||
operSpecialJudgeDelBtn: {
|
||
type: [String, Array],
|
||
required: false,
|
||
default: ''
|
||
}
|
||
},
|
||
data () {
|
||
return {
|
||
// settingVisible: false,
|
||
// 设置表格
|
||
settingColumns: [
|
||
{ title: '列名', dataIndex: 'title', align: 'center', ellipsis: true, width: 150 },
|
||
{
|
||
title: '隐藏',
|
||
dataIndex: 'hide',
|
||
align: 'center',
|
||
ellipsis: true,
|
||
width: 60,
|
||
scopedSlots: { customRender: 'hide' }
|
||
},
|
||
{
|
||
title: '冻结',
|
||
dataIndex: 'freeze',
|
||
align: 'center',
|
||
ellipsis: true,
|
||
width: 60,
|
||
scopedSlots: { customRender: 'freeze' }
|
||
}
|
||
],
|
||
settingDataSource: [],
|
||
settingColumnsObj: { hide: [], freeze: [] }, // 本地存储的配置对象
|
||
resultColumns: [],
|
||
components: {
|
||
header: {
|
||
cell: this.initDrag(this.columns)
|
||
}
|
||
},
|
||
selfScroll: {}
|
||
}
|
||
},
|
||
watch: {
|
||
// 配置列改变,将配置转换成配置表格数据
|
||
settingColumnsObj: {
|
||
deep: true, // 深度监听
|
||
immediate: true, // 挂载先执行一次
|
||
handler () {
|
||
const dataSource = []
|
||
this.columns.forEach(col => {
|
||
const tempKey = getKey(col)
|
||
// 操作栏不可配置
|
||
if (tempKey === actionKey) {
|
||
return
|
||
}
|
||
// hideSettingColumn: true 可以让不显示字段控制
|
||
if (col.hideSettingColumn) {
|
||
return
|
||
}
|
||
dataSource.push({
|
||
title: col.title || col.columnTitle, // 用于显示的字段
|
||
key: tempKey, // 用于存储的字段
|
||
hide: this.settingColumnsObj.hide.includes(tempKey), // 是否隐藏
|
||
freeze: this.settingColumnsObj.freeze.includes(tempKey), // 是否冻结
|
||
disabledHide: col.disabledHide, // 禁用隐藏
|
||
disabledFreeze: col.disabledFreeze // 禁用冻结
|
||
})
|
||
})
|
||
this.settingDataSource = dataSource
|
||
// 自定义列配置修改后,更新表格字段
|
||
this.setResultColumns(this.columns)
|
||
}
|
||
},
|
||
columns: {
|
||
handler () {
|
||
this.setResultColumns(this.columns)
|
||
},
|
||
deep: true
|
||
}
|
||
},
|
||
methods: {
|
||
isHasPermission,
|
||
// 操作列特殊判断,返回经过特殊判断后的操作列数据
|
||
operSpecialJudge (record) {
|
||
let operationList = []
|
||
if (typeof this.operSpecialJudgeValue === 'boolean' || typeof this.operSpecialJudgeValue === 'string') {
|
||
// 只需要判断某个字段是否符合某一个值
|
||
if (record[this.operSpecialJudgeField] === this.operSpecialJudgeValue) {
|
||
// 符合特殊条件,需要过滤操作按钮
|
||
if (this.operSpecialJudgeDelBtn && typeof this.operSpecialJudgeDelBtn === 'string') {
|
||
// 是字符串类型,只需要过滤掉一个操作按钮
|
||
operationList = this.operationList.filter(item => item.text !== this.operSpecialJudgeDelBtn)
|
||
} else if (this.operSpecialJudgeDelBtn && typeof this.operSpecialJudgeDelBtn === 'object') {
|
||
// 是数组类型需要过滤掉多个操作按钮
|
||
operationList = this.operationList.filter(item => !this.operSpecialJudgeDelBtn.includes(item.text))
|
||
} else {
|
||
operationList = this.operationList
|
||
}
|
||
} else {
|
||
// 不符合条件,不需要过滤
|
||
operationList = this.operationList
|
||
}
|
||
} else if (typeof this.operSpecialJudgeValue === 'object') {
|
||
// 需要判断某个字段是否符合某些值
|
||
if (this.operSpecialJudgeValue.includes(record[this.operSpecialJudgeField])) {
|
||
// 符合特殊条件,需要过滤操作按钮
|
||
if (this.operSpecialJudgeDelBtn && typeof this.operSpecialJudgeDelBtn === 'string') {
|
||
// 是字符串类型,只需要过滤掉一个操作按钮
|
||
operationList = this.operationList.filter(item => item.text !== this.operSpecialJudgeDelBtn)
|
||
} else if (this.operSpecialJudgeDelBtn && typeof this.operSpecialJudgeDelBtn === 'object') {
|
||
// 师叔祖类型需要过滤掉多个操作按钮
|
||
operationList = this.operationList.filter(item => !this.operSpecialJudgeDelBtn.includes(item.text))
|
||
} else {
|
||
operationList = this.operationList
|
||
}
|
||
} else {
|
||
// 不符合条件,不需要过滤
|
||
operationList = this.operationList
|
||
}
|
||
}
|
||
return operationList
|
||
},
|
||
// 操作栏按钮点击
|
||
operationClick (operation, record) {
|
||
this.$emit('operationClick', operation, record)
|
||
},
|
||
// 将父组件的columns进行处理:增加设置列按钮
|
||
setResultColumns (columns) {
|
||
// 深度克隆,防止直接修改父组件数据
|
||
columns = cloneDeep(columns)
|
||
// 有设置功能再进行这个插槽的配置
|
||
if (this.needSettingColumnHideOrFreeze) {
|
||
// 设置按钮插槽配置
|
||
const settingOption = {
|
||
filterDropdown: 'settingDropdown',
|
||
filterIcon: 'settingIcon'
|
||
}
|
||
let findActionIndex = columns.findIndex(col => col && (getKey(col) === actionKey))
|
||
// 将设置按钮放到表格右上角,如果有操作栏就固定到右侧(操作栏固定右侧,没有的话就最后一列)
|
||
if (findActionIndex === -1) {
|
||
findActionIndex = columns.length - 1
|
||
}
|
||
if (columns[findActionIndex].scopedSlots instanceof Object) {
|
||
Object.assign(columns[findActionIndex].scopedSlots, settingOption)
|
||
} else {
|
||
columns[findActionIndex].scopedSlots = settingOption
|
||
}
|
||
// 自定义设置弹框(尝试解决表格刷新丢失弹框的问题)此方法会出现两个弹框
|
||
// columns[findActionIndex].filterDropdownVisible = this.settingVisible
|
||
// columns[findActionIndex].onFilterDropdownVisibleChange = (visible) => {
|
||
// this.settingVisible = visible
|
||
// }
|
||
}
|
||
|
||
// 最后过滤掉需要隐藏的字段,按定位进行排序
|
||
const startArr = [] // 冻结左侧的列
|
||
const midArr = [] // 没有冻结的列
|
||
const endArr = [] // 冻结右侧的列(只能是action,暂时不能自定义固定右侧)
|
||
columns.forEach(col => {
|
||
const key = getKey(col)
|
||
// 如果不需要配置冻结列,就按表头本身传的参数决定固定列
|
||
const fixed = this.needSettingColumnHideOrFreeze ? this.settingColumnsObj.freeze.includes(key) : col.fixed
|
||
col.hide = this.settingColumnsObj.hide.includes(key)
|
||
col.fixed = fixed
|
||
// 如果是字符串就转换成数字(因为实现拖拽,单位只能是px)
|
||
col.width = col.width && parseInt(col.width + '')
|
||
// 如果没有最小宽度就获取统一设置的最小宽度
|
||
col.minWidth = (col.minWidth && parseInt(col.minWidth + '')) || this.columnMinWidth
|
||
// 如果没有配置align,就默认居中
|
||
col.align = col.align || 'center'
|
||
if (!col.scopedSlots) {
|
||
col.scopedSlots = {
|
||
customRender: 'text'
|
||
}
|
||
}
|
||
if (!col.hide) {
|
||
// 如果没有宽度就取minWidth(不添加原数据的width属性,这里只对需要固定的minWidth生效)
|
||
const width = col.width || col.minWidth
|
||
switch (col.fixed) {
|
||
case true:
|
||
case 'left':
|
||
startArr.push({ ...col, width })
|
||
break
|
||
case 'right':
|
||
endArr.push({ ...col, width })
|
||
break
|
||
default:
|
||
midArr.push(col)
|
||
}
|
||
}
|
||
})
|
||
// 更新父组件的数据,将排序后的进行渲染
|
||
this.$emit('update:columns', columns)
|
||
// 按冻结顺序排序
|
||
this.resultColumns = [
|
||
...startArr.sort((a, b) => {
|
||
const freezeArr = this.settingColumnsObj.freeze
|
||
return freezeArr.indexOf(getKey(a)) - freezeArr.indexOf(getKey(b))
|
||
}),
|
||
...midArr,
|
||
...endArr
|
||
]
|
||
return this.resultColumns
|
||
},
|
||
// 初始化表格拖拽
|
||
initDrag (columns) {
|
||
// 根据配置项决定是否可以拖拽,本身是根据是否有边框配置的,但是有边框且有固定操作列的情况下,拖动会有一个空白列
|
||
if (!this.canDrag) {
|
||
return
|
||
}
|
||
// 如果没有任何列开启拖拽就不需要拖拽
|
||
// if (!columns.some(col => col.resizable)) {
|
||
// return
|
||
// }
|
||
// 第一步:列宽映射
|
||
const draggingMap = {}
|
||
columns.forEach((col) => {
|
||
draggingMap[getKey(col)] = col.width
|
||
})
|
||
const draggingState = Vue.observable(draggingMap)
|
||
// 第二步:表头渲染
|
||
return (h, props, children) => {
|
||
// 表头DOM
|
||
let thDom = null
|
||
// 获取列的key值和特性
|
||
const { key, ...restProps } = props
|
||
// 获取最新列配置
|
||
const columns = cloneDeep(this.columns)
|
||
let col
|
||
if (key === 'selection-column') {
|
||
col = {}
|
||
} else {
|
||
col = columns.find(col => getKey(col) === key) || {}
|
||
}
|
||
// 没有开启拖拽 或 没有宽度 或 有定位,都不能拖拽(防止布局异常,至少有一列不设width并且不能有fixed)
|
||
if (!col.width || !!col.fixed) {
|
||
return <th {...restProps}>{children}</th>
|
||
}
|
||
// 开始拖拽监听
|
||
const onDragging = (x) => {
|
||
const beforeWidth = col.width
|
||
const scroll = cloneDeep(this.scroll) || {}
|
||
draggingState[key] = 0
|
||
col.width = Math.max(x, col.minWidth || this.columnMinWidth)
|
||
// 如果有scroll.x就计算差值,否则获取所有列的和
|
||
if (scroll.x) {
|
||
scroll.x = scroll.x + (col.width - beforeWidth)
|
||
} else {
|
||
scroll.x = 0
|
||
this.columns.forEach(col => (scroll.x += (col.width || col.minWidth || this.columnMinWidth)))
|
||
}
|
||
// 将计算好的宽度更新
|
||
if (this.scroll) {
|
||
this.$emit('update:scroll', scroll)
|
||
} else {
|
||
this.selfScroll = scroll
|
||
}
|
||
// 解决拖拽重置其他单元格宽度的问题
|
||
const colIndex = this.resultColumns.findIndex(tt => getKey(tt) === key)
|
||
const nowResultColumns = cloneDeep(this.resultColumns)
|
||
nowResultColumns.splice(colIndex, 1, col)
|
||
// 修改列宽后,更新表格字段
|
||
this.setResultColumns(nowResultColumns)
|
||
}
|
||
// 停止拖拽监听
|
||
const onDragstop = () => {
|
||
draggingState[key] = thDom.getBoundingClientRect().width
|
||
}
|
||
// 控制最小拖拽宽度
|
||
const onDrag = (x) => {
|
||
return x >= (col.minWidth || this.columnMinWidth)
|
||
}
|
||
// 解决都有dataIndex时会有横向滚动条的问题,让最后一列的拖拽容器宽度为0
|
||
return (
|
||
<th
|
||
{...restProps}
|
||
v-ant-ref={(r) => (thDom = r)}
|
||
width={col.width}
|
||
class="resize-table-th"
|
||
>
|
||
{children}
|
||
<vue-draggable-resizable
|
||
key={getKey(col)}
|
||
class="table-draggable-handle"
|
||
minw={10}
|
||
w={10}
|
||
x={col.width || draggingState[key]}
|
||
z={1}
|
||
axis="x"
|
||
draggable={true}
|
||
resizable={false}
|
||
props={{ onDrag }}
|
||
onDragging={onDragging}
|
||
onDragstop={onDragstop}
|
||
></vue-draggable-resizable>
|
||
</th>
|
||
)
|
||
}
|
||
},
|
||
/**
|
||
* 配置表中复选框改变状态的事件
|
||
* @param text 修改前的状态
|
||
* @param type 隐藏还是冻结
|
||
* @param record 当前行数据
|
||
*/
|
||
changeSetting (text, type, record) {
|
||
const checked = !text // text是点击前的状态,取反就是要修改的状态
|
||
// console.log('修改了配置', checked, type, record)
|
||
// 修改当前行配置
|
||
record[type] = !checked
|
||
// 勾选就添加,取消就删除
|
||
if (checked) {
|
||
this.settingColumnsObj[type].push(record.key)
|
||
} else {
|
||
this.settingColumnsObj[type].splice(this.settingColumnsObj[type].findIndex(item => item === record.key), 1)
|
||
}
|
||
this.saveSetting()
|
||
/**
|
||
* 弹框消失问题 冻结列出现和消失会导致dom结构改变而从更新结构丢失弹框
|
||
* 解决方案,刷新前获取dom,刷新后再次获取,如果获取不一致就触发点击事件点开弹框
|
||
*/
|
||
const beforeIsFixed = !!this.$refs.table.$el.querySelector('.ant-table-fixed-left')
|
||
this.$nextTick(() => {
|
||
const afterIsFixed = !!this.$refs.table.$el.querySelector('.ant-table-fixed-left')
|
||
// console.log(beforeIsFixed !== afterIsFixed)
|
||
if (beforeIsFixed !== afterIsFixed) {
|
||
this.$refs.settingBtn.$el.click()
|
||
}
|
||
})
|
||
},
|
||
// 初始化配置,从columns里获取
|
||
initSetting (columns) {
|
||
const hide = []
|
||
const freeze = []
|
||
columns.forEach(col => {
|
||
const key = getKey(col)
|
||
// hide属性控制隐藏
|
||
if (col.hide) {
|
||
hide.push(key)
|
||
}
|
||
// fixed冻结到左侧
|
||
if (col.fixed === true || col.fixed === 'left') {
|
||
freeze.push(key)
|
||
}
|
||
})
|
||
this.settingColumnsObj = { hide, freeze }
|
||
this.saveSetting()
|
||
},
|
||
// 配置保存到本地
|
||
saveSetting () {
|
||
if (!this.needSaveSettingInLocal) {
|
||
return
|
||
}
|
||
// 获取所有的jtable缓存的key数组(用于清除缓存,没有就初始化数组)
|
||
const jTableKeys = Vue.ls.get(J_TABLE_KEYS) || []
|
||
const saveKey = this.tableKey + saveSuffix
|
||
// 如果不在数组里面就追加进去
|
||
if (!jTableKeys.includes(saveKey)) {
|
||
jTableKeys.push(saveKey)
|
||
}
|
||
Vue.ls.set(J_TABLE_KEYS, jTableKeys, 7 * 24 * 60 * 60 * 10)
|
||
Vue.ls.set(saveKey, this.settingColumnsObj, 7 * 24 * 60 * 60 * 10)
|
||
},
|
||
// 还原默认配置
|
||
resteColumns () {
|
||
this.initSetting(this.columnsBak)
|
||
},
|
||
// 清除本地的配置(当前的JTable)
|
||
clearSetting () {
|
||
this.settingColumnsObj = { hide: [], freeze: [] }
|
||
Vue.ls.remove(this.tableKey + saveSuffix)
|
||
this.resteColumns()
|
||
this.$message.success('成功清除当前JTable的缓存!')
|
||
},
|
||
// 清除所有缓存
|
||
clearAllCacheSetting () {
|
||
// 获取到之后遍历删除,最后把keys数组删除
|
||
const jTableKeys = Vue.ls.get(J_TABLE_KEYS)
|
||
jTableKeys && jTableKeys.forEach(key => {
|
||
Vue.ls.remove(key)
|
||
})
|
||
Vue.ls.remove(J_TABLE_KEYS)
|
||
this.resteColumns() // 这里只能刷新当前的表
|
||
this.$message.success('成功清除全局JTable的缓存!')
|
||
},
|
||
getLineOperationList (record) {
|
||
const hasPermissionList = this.operationList.filter(tt => !tt.has || isHasPermission(tt.has))
|
||
const lineOperateList = []
|
||
hasPermissionList.forEach(item => {
|
||
if (!item.show) {
|
||
lineOperateList.push(item)
|
||
} else if (typeof item.show === 'function') {
|
||
if (item.show(record)) {
|
||
lineOperateList.push(item)
|
||
}
|
||
}
|
||
})
|
||
return lineOperateList
|
||
}
|
||
},
|
||
mounted () {
|
||
// 备份默认配置
|
||
this.columnsBak = cloneDeep(this.columns)
|
||
let settingColumnsObj
|
||
if (this.needSaveSettingInLocal) {
|
||
settingColumnsObj = Vue.ls.get(this.tableKey + saveSuffix)
|
||
}
|
||
// 第一次进页面或清空缓存进行初始化
|
||
if (settingColumnsObj) {
|
||
this.settingColumnsObj = settingColumnsObj
|
||
} else {
|
||
this.initSetting(this.columns)
|
||
}
|
||
},
|
||
created () {
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less">
|
||
.j-table {
|
||
.resize-table-th {
|
||
position: relative;
|
||
// 让拖动的地方有个线
|
||
border-right: 1px #e8e8e8 solid;
|
||
|
||
.table-draggable-handle {
|
||
transform: none !important;
|
||
position: absolute !important;
|
||
height: 100% !important;
|
||
bottom: 0;
|
||
left: auto !important;
|
||
right: -5px;
|
||
//width: 10px !important;
|
||
cursor: col-resize;
|
||
touch-action: none;
|
||
}
|
||
}
|
||
|
||
// 解决每行都有dataIndex时会有横向滚动条的问题
|
||
.resize-table-th:last-child {
|
||
border-right: none;
|
||
|
||
.table-draggable-handle {
|
||
width: 0px !important;
|
||
min-width: 0px !important;
|
||
}
|
||
}
|
||
}
|
||
</style>
|