1
lzhe
2024-06-03 a786409d7f6769f43c107159dd84faf4a2927a9a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!--
 * @Descripttion: 表单表格
 * @version: 1.3
 * @Author: sakuya
 * @Date: 2023年2月9日12:32:26
 * @LastEditors: Sneed
 * @LastEditTime: 2024-04-17 22:09:27
-->
 
<template>
    <div class="sc-form-table" ref="scFormTable">
        <el-table :data="data" ref="table" border stripe>
            <el-table-column type="index" width="50" fixed="left">
                <template #header>
                    <el-button v-if="!hideAdd" type="primary" icon="el-icon-plus" size="small" circle
                        @click="rowAdd"></el-button>
                </template>
                <template #default="scope">
                    <div :class="['sc-form-table-handle', { 'sc-form-table-handle-delete': !hideDelete }]">
                        <span>{{ scope.$index + 1 }}</span>
                        <el-popconfirm v-if="!scope.row.isSet" title="确定删除吗?"
                            @confirm="rowDel(scope.row, scope.$index)">
                            <template #reference>
                                <el-button v-if="!hideDelete" type="danger" icon="el-icon-delete" size="small" plain
                                    circle></el-button>
                                <!-- <el-button text type="primary" size="small">删除</el-button> -->
                            </template>
                        </el-popconfirm>
 
                    </div>
                </template>
            </el-table-column>
            <el-table-column label="" width="50" v-if="dragSort">
                <template #default>
                    <div class="move" style="cursor: move;"><el-icon-d-caret style="width: 1em; height: 1em;" /></div>
                </template>
            </el-table-column>
            <slot></slot>
            <template #empty>
                {{ placeholder }}
            </template>
        </el-table>
    </div>
</template>
 
<script>
import Sortable from 'sortablejs'
 
export default {
    props: {
        modelValue: { type: Array, default: () => [] },
        addTemplate: { type: Object, default: () => { } },
        placeholder: { type: String, default: "暂无数据" },
        dragSort: { type: Boolean, default: false },
        hideAdd: { type: Boolean, default: false },
        hideDelete: { type: Boolean, default: false }
    },
    data() {
        return {
            data: []
        }
    },
    mounted() {
        this.data = this.modelValue
        if (this.dragSort) {
            this.rowDrop()
        }
    },
    watch: {
        modelValue() {
            this.data = this.modelValue
        },
        data: {
            handler() {
                this.$emit('update:modelValue', this.data);
            },
            deep: true
        }
    },
    methods: {
        rowDrop() {
            const _this = this
            const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
            Sortable.create(tbody, {
                handle: ".move",
                animation: 300,
                ghostClass: "ghost",
                onEnd({ newIndex, oldIndex }) {
 
                    _this.data.splice(newIndex, 0, _this.data.splice(oldIndex, 1)[0])
                    const newArray = _this.data.slice(0)
                    const tmpHeight = _this.$refs.scFormTable.offsetHeight
                    _this.$refs.scFormTable.style.setProperty('height', tmpHeight + 'px')
                    _this.data = []
                    _this.$nextTick(() => {
                        _this.data = newArray
                        _this.$nextTick(() => {
                            _this.$emit('rowDrop', newArray)
                            _this.$refs.scFormTable.style.removeProperty('height')
                        })
 
                    })
                }
            })
        },
        rowAdd() {
            const temp = JSON.parse(JSON.stringify(this.addTemplate))
            this.data.push(temp)
        },
        rowDel(row, index) {
            this.$emit('delRow', row)
            this.data.splice(index, 1)
        },
        //插入行
        pushRow(row) {
            const temp = row || JSON.parse(JSON.stringify(this.addTemplate))
            this.data.push(temp)
        },
        //根据index删除
        deleteRow(index) {
            this.data.splice(index, 1)
        }
    }
}
</script>
 
<style scoped>
.sc-form-table {
    width: 100%;
}
 
.sc-form-table .sc-form-table-handle {
    text-align: center;
}
 
.sc-form-table .sc-form-table-handle span {
    display: inline-block;
}
 
.sc-form-table .sc-form-table-handle button {
    display: none;
}
 
.sc-form-table .hover-row .sc-form-table-handle-delete span {
    display: none;
}
 
.sc-form-table .hover-row .sc-form-table-handle-delete button {
    display: inline-block;
}
 
.sc-form-table .move {
    text-align: center;
    font-size: 14px;
    margin-top: 3px;
}
</style>