feat: 增加表格快捷操作

pull/22/head
xlzy 2021-02-11 18:56:22 +08:00
parent 94cb153aa8
commit 4314fc52f2
5 changed files with 266 additions and 6 deletions

View File

@ -30,6 +30,7 @@
"nprogress": "^0.2.0",
"print-js": "^1.0.63",
"raphael": "^2.3.0",
"screenfull": "^5.1.0",
"viser-vue": "^2.4.6",
"vue": "^2.6.10",
"vue-clipboard2": "^0.2.1",

View File

@ -0,0 +1,81 @@
<template>
<div slot="overlay" class="ant-dropdown-menu s-tool-column ant-dropdown-content">
<div class="s-tool-column-header s-tool-column-item">
<a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">
列展示
</a-checkbox>
<a @click="reset"></a>
</div>
<a-divider />
<div class="ant-checkbox-group">
<div>
<draggable v-model="columnsSetting" animation="300" @end="dragEnd">
<div class="s-tool-column-item" v-for="item in columnsSetting" :key="item.title">
<div class="s-tool-column-handle" >
<a-icon type="more"/>
<a-icon type="more"/>
</div>
<a-checkbox v-model="item.checked" @change="onChange">{{ item.title }}</a-checkbox>
</div>
</draggable>
</div>
</div>
<!-- <a-checkbox-group v-model="checkedList" :options="optionsWithDisabled" @change="onChange" >-->
<!-- </a-checkbox-group>-->
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
props: {
columns: {
type: Array,
default: () => ([])
}
},
components: {
draggable
},
data() {
return {
indeterminate: false,
checkAll: true,
columnsSetting: [],
originColumns: []
}
},
methods: {
reset() {
this.columnsSetting = this.originColumns
this.indeterminate = false
this.checkAll = true
},
onChange() {
const checkedList = this.columnsSetting.filter(value => value.checked)
this.indeterminate = !!checkedList.length && checkedList.length < this.columnsSetting.length
this.checkAll = checkedList.length === this.columnsSetting.length
this.$emit('columnChange', this.columnsSetting)
},
onCheckAllChange(e) {
const val = e.target.checked
Object.assign(this, {
indeterminate: false,
checkAll: val,
columnsSetting: this.columns.map(value => ({ ...value, checked: val }))
})
},
dragEnd() {
this.$emit('columnChange', this.columnsSetting)
}
},
mounted() {
this.columnsSetting = this.columns.map(value => ({ ...value, checked: true }))
this.originColumns = [...this.columnsSetting]
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -1,7 +1,14 @@
import T from 'ant-design-vue/es/table/Table'
import get from 'lodash.get'
import screenfull from 'screenfull'
import draggable from 'vuedraggable'
import columnSetting from './columnSetting'
import './index.less'
export default {
components: {
draggable, columnSetting
},
data () {
return {
needTotalList: [],
@ -11,7 +18,15 @@ export default {
localLoading: false,
localDataSource: [],
localPagination: Object.assign({}, this.pagination)
localPagination: Object.assign({}, this.pagination),
isFullscreen: false,
customSize: this.size,
// 列配置
indeterminate: true,
checkAll: false,
checkedList: [],
columnsSetting: []
}
},
props: Object.assign({}, T.props, {
@ -74,6 +89,10 @@ export default {
pageURI: {
type: Boolean,
default: false
},
extraTool: {
type: Array,
default: () => ([])
}
}),
watch: {
@ -116,6 +135,7 @@ export default {
// console.log('this.localPagination', this.localPagination)
this.needTotalList = this.initTotalList(this.columns)
this.loadData()
this.columnsSetting = this.columns
},
methods: {
/**
@ -276,11 +296,109 @@ export default {
</template>
</a-alert>
) */
},
columnChange(val) {
this.columnsSetting = val
},
renderHeader () {
let tools = [
{
icon: 'reload',
title: '',
onClick: () => {
this.refresh()
}
},
{
icon: 'column-height',
title: '',
isDropdown: true,
menu: () => {
const onClick = ({ key }) => {
this.customSize = key
}
return (
<a-menu slot="overlay" onClick={onClick} selectable defaultSelectedKeys={[this.customSize]}>
<a-menu-item key="default"></a-menu-item>
<a-menu-item key="middle"></a-menu-item>
<a-menu-item key="small"></a-menu-item>
</a-menu>
)
},
onClick: () => {
}
},
{
icon: 'setting',
title: '',
isDropdown: true,
menu: () => {
return <columnSetting slot="overlay" columns={this.columns} onColumnChange={this.columnChange} />
},
onClick: () => {
}
},
{
icon: this.isFullscreen ? 'fullscreen-exit' : 'fullscreen',
title: '',
onClick: () => {
if (screenfull.isEnabled) {
const table = document.querySelector('.table-wrapper')
const antdCard = table.parentNode.parentNode
if (antdCard.classList.contains('ant-card')) {
screenfull.toggle(antdCard)
this.isFullscreen = !this.isFullscreen
}
}
}
}
]
if (this.extraTool.length) {
tools = tools.concat(this.extraTool)
}
return (
<div class="s-table-tool">
<div class="s-table-tool-left">
{this.$scopedSlots.operator()}
</div>
<div class="s-table-tool-right">
{
tools.map(tool => {
if (tool.isDropdown) {
return (
<a-dropdown trigger={['click']}>
<a-tooltip title={tool.title} class="s-tool-item" onClick={tool.onClick}>
<a-icon type={tool.icon}/>
</a-tooltip>
{ tool.menu() }
</a-dropdown>
)
}
return (
<a-tooltip title={tool.title} class="s-tool-item" onClick={tool.onClick}>
<a-icon type={tool.icon} />
</a-tooltip>
)
})
}
</div>
</div>
)
/* return (
<a-alert showIcon={true} style="margin-bottom: 16px">
<template slot="message">
<span style="margin-right: 12px">: <a style="font-weight: 600">{this.selectedRows.length}</a></span>
{needTotalItems}
{clearItem}
</template>
</a-alert>
) */
}
},
render () {
const props = {}
let props = {}
const localKeys = Object.keys(this.$data)
const showAlert = (typeof this.alert === 'object' && this.alert !== null && this.alert.show) && typeof this.rowSelection.selectedRowKeys !== 'undefined' || this.alert
@ -311,6 +429,12 @@ export default {
}
}
this[k] && (props[k] = this[k])
// 此处配置表格大小与要显示的列
props = {
...props,
size: this.customSize,
columns: this.columnsSetting.filter(value => value.checked === undefined || value.checked)
}
return props[k]
})
const table = (
@ -321,6 +445,7 @@ export default {
return (
<div class="table-wrapper">
{ this.renderHeader() }
{ showAlert ? this.renderAlert() : null }
{ table }
</div>

View File

@ -0,0 +1,54 @@
.table-wrapper{
background: #fff;
}
.s-table-tool{
display: flex;
margin-bottom: 16px;
.s-table-tool-left{
flex: 1;
}
.s-table-tool-right{
display: inline-flex;
align-items: center;
.s-tool-item{
font-size: 16px;
margin-left: 16px;
cursor: pointer;
}
}
}
.s-tool-column-item{
display: flex;
align-items: center;
padding: 4px 16px 4px 4px;
.ant-checkbox-wrapper{
flex: 1;
}
.s-tool-column-handle{
opacity: .8;
cursor: move;
.anticon-more{
font-size: 12px;
margin-top: 2px;
& + .anticon-more{
margin: 2px 4px 0 -8px;
}
}
}
}
.s-tool-column-header{
padding: 5px 16px 10px 24px;
min-width: 180px;
}
.s-tool-column{
.ant-divider{
margin: 0;
}
.ant-checkbox-group{
padding: 4px 0;
display: block;
}
}

View File

@ -43,10 +43,6 @@
</a-form>
</div>
<div class="table-operator" v-if="hasPerm('sysUser:add')" >
<a-button type="primary" v-if="hasPerm('sysUser:add')" icon="plus" @click="$refs.addForm.add()"></a-button>
</div>
<s-table
ref="table"
size="default"
@ -56,6 +52,9 @@
:rowKey="(record) => record.id"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
>
<template slot="operator" v-if="hasPerm('sysUser:add')">
<a-button type="primary" v-if="hasPerm('sysUser:add')" icon="plus" @click="$refs.addForm.add()"></a-button>
</template>
<span slot="sex" slot-scope="text">
{{ sexFilter(text) }}
</span>