JEECG BOOT 低代码开发平台Vue2版实现自定义列(排序、列宽)

674 阅读1分钟

最近在使用JEECG BOOT低代码平台的时候,发现表格Vue2版本没有Vue3版本的自定义列的功能,于是乎,我自己动手写了。

Vue3版本的自定义列:

image.png

自己写的Vue2版本的:

image.png

本次是写成了一个组件,当然你也可以将dom部分加到模板中,js写到Mixin中 组件代码:

  <a-popover trigger="click" placement="leftBottom">
    <template slot="title">
      <a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">
        自定义列
      </a-checkbox>
    </template>
    <template slot="content">
      <span class="span_title">注:拖动进行排序,不输入和输入非大于0都是自适应宽度。</span>
      <a-checkbox-group @change="onColSettingsChange" v-model="settingColumns" :defaultValue="settingColumns">
        <draggable v-model="defColumns" filter=".forbid" animation="300" @start="onStart" @end="onEnd">
          <transition-group>

            <template v-for="(item,index) in defColumns">
              <a-row class="item" :class="item.key=='rowIndex'|| item.dataIndex=='action'?'item forbid':''" :key="item.title" style="margin-top:10px">
                <div @mouseenter="mouseEnter(index)" @mouseleave="mouseLeave(index)">
                  <a-checkbox default-checked :disabled="item.key=='rowIndex'|| item.dataIndex=='action'" :value="item.title">{{ item.title }}</a-checkbox>
                  <template v-if="item.key!='rowIndex'&&item.dataIndex!='action'">
                    <img v-show="showDrag===index" :src="dragSvg" alt="">
                  </template>
                </div>
                <div>
                  <span>宽度</span>
                  <a-input :disabled="item.key=='rowIndex'|| item.dataIndex=='action'" v-model.number="item.width" :placeholder="item.dataIndex=='action'?'auto':'请输入'" clearable ></a-input>
                  <span>px</span>
                </div>
              </a-row>
            </template>
          </transition-group>
        </draggable>
      </a-checkbox-group>
    </template>
    <a class="floatRight"><a-icon type="setting" />自定义列</a>
  </a-popover>
</template>

<script>
import dragSvg from '@/assets/drag_svg.svg'
import Vue from 'vue'
import draggable from 'vuedraggable'
import _ from 'lodash'
export default {
    name: 'CustomColumn',
    props: {
        columns: {
            type: Array,
            required: true
        }
    },
    components: { draggable },
    data() {
        return {
            dragSvg,
            showDrag: null,
            selKey: '',
            colKey: '',
            settingColumns: [], // 列设置
            defColumns: [], // 列定义
            indeterminate: true,
            checkAll: false
        }
    },
    methods: {
        // 更新列
        updetaColumn() {
            const cols = this.defColumns.filter(item => {
                if (item.key === 'rowIndex' || item.dataIndex === 'action') {
                return true
                }
                if (this.settingColumns.includes(item.title)) {
                return true
                }
                return false
            })
            this.$emit('update:columns', cols)
        },
        // 开始拖拽事件
        onStart(evt) {},
        // 拖拽结束事件
        onEnd(evt) {
            this.updetaColumn()
        },
        // 列设置更改事件
        onColSettingsChange (checkedValues) {
            this.indeterminate = !!checkedValues.length && checkedValues.length < this.defColumns.length
            this.checkAll = checkedValues.length === this.defColumns.length
            Vue.ls.set(this.selKey, checkedValues, 7 * 24 * 60 * 60 * 1000)
            this.settingColumns = checkedValues
            this.updetaColumn()
        },
        // 列全选事件
        onCheckAllChange({ target }) {
            Object.assign(this, {
                settingColumns: target.checked ? this.defColumns.map(item => item.title) : this.defColumns.filter(item => item.key === 'rowIndex' || item.dataIndex === 'action').map(item => item.title),
                indeterminate: true,
                checkAll: target.checked
            })
            Vue.ls.set(this.selKey, this.settingColumns, 7 * 24 * 60 * 60 * 1000)
            this.updetaColumn()
        },
        // 初始化
        initColumns() {
            this.selKey = this.$route.name + ':colsettings'
            this.colKey = this.$route.name + ':columns'
            this.defColumns = Vue.ls.get(this.colKey) || _.cloneDeep(this.columns)
            this.defColumns.forEach(item => {
                if (item.key === 'rowIndex') {
                    item.customRender = (t, r, i) => i + 1
                }
            })
            let colSettings = Vue.ls.get(this.selKey)
            if (colSettings == null || colSettings === undefined) {
                // 如果没有存储,默认全选
                let allSettingColumns = []
                this.defColumns.forEach(function (item, i, array) {
                    allSettingColumns.push(item.title)
                })
                this.settingColumns = allSettingColumns
                this.indeterminate = false
                this.checkAll = true
                this.$emit('update:columns', this.defColumns)
            } else {
                this.settingColumns = colSettings
                this.indeterminate = !!this.settingColumns.length && this.settingColumns.length < this.defColumns.length
                this.checkAll = this.settingColumns.length === this.defColumns.length
                this.updetaColumn()
            }
        },
        mouseEnter(index) {
            this.showDrag = index
        },
        mouseLeave() {
            this.showDrag = null
        }
    },
    created() {
        this.initColumns()
    },
    computed: {},
    watch: {
        defColumns: {
            deep: true,
            handler(newValue, oldValue) {
                Vue.ls.set(this.colKey, newValue, 7 * 24 * 60 * 60 * 1000)
                this.updetaColumn()
            }
        }
    }
}
</script>

<style scoped lang='less'>
    /** 表格自定义列靠右样式 */
    .floatRight{
        float: right;
    }
    .ant-input{
        width: 100px;
        margin: 0 10px;
    }
    .ant-checkbox-group{
        display: block;
    }
    .item{
        display: flex;
        justify-content: space-between;
        align-items: center;
        div{
            min-width: 200px;
        }
        img{
            height: 16px;
            cursor: move;
        }
    }
</style>

使用:

image.png

image.png

image.png

如果有写的不好的地方,请多多指点!!!