mirror of https://gitee.com/xiaonuobase/snowy
feat: 增加表格快捷操作
parent
94cb153aa8
commit
4314fc52f2
|
@ -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",
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue