<template>
<div class="elian--table-field">
<div class="elian--table-field-left">
<div class="elian--table-field-title">
<div class="title-left">
<span>全部字段</span>
<span>({{dataLen}})</span>
</div>
<div class="title-right title-hover">
<span clss="fs14" @click="handleCheckAll">全选</span>
</div>
</div>
<div class="elian--table-field-list p12 bb b-c b-r-10">
<div class="elian--table-field-list-item" v-for="(item,index) in dataList" :key="index">
<el-checkbox v-model="item[check]" @change="handlecheckItem(item,index)">{{item[label]}}</el-checkbox>
</div>
</div>
</div>
<div class="elian--table-field-center">
<i class="el-icon-arrow-right fs22" />
</div>
<div class="elian--table-field-right">
<div class="elian--table-field-title">
<div class="title-left">
<span>已选字段</span>
<span>({{ checkLen + "/" + dataLen}})</span>
</div>
<div class="title-right title-hover">
<span clss="fs14" @click="handleClear">清空</span>
</div>
</div>
<div class="elian--table-field-list p12 bb b-c b-r-10">
<Draggable v-model="checkDataList" @change="handleChange" @start="handleStart" class="grid-container"
@end="handleEnd" :options="{ handle: '.drag-handle' }">
<div class="elian--table-field-list-item list-item" v-for="(item,index) in checkDataList" :key="index">
<!-- <i class="el-icon-rank fs16 title-hover drag-handle" /> -->
<img src="@/assets/imgs/drag_icon.png" alt="" class="drag-handle">
<span class="fs14 list-item-title">{{item[label]}}</span>
<i class="el-icon-close fs16 m-l title-hover" @click="handleDel(item,index)" />
</div>
</Draggable>
</div>
</div>
<div class="elian--table-field-footer">
<div class="fs14 footer-left " @click="handleDefaultSet">
<span class="title-hover">恢复默认设置</span>
<div class="footer-tips">
<img class="img6" src="@/assets/imgs/tips_icon.png" alt="">
<span class="fs12 c5">清理浏览器缓存将恢复默认设置</span>
</div>
</div>
<div>
<el-button type="primary" plain size="mini" @click="handleClose">取消</el-button>
<el-button type="primary" size="mini" @click="handleSave">保存</el-button>
</div>
</div>
</div>
</template>
<script>
import Draggable from 'vuedraggable'
import cryptoJS from "crypto-js"
export default {
name: 'TableFieldSet',
components: {
Draggable
},
props: {
data: {
type: Array,
default: () => []
},
value: {
type: String,
default: 'value'
},
label: {
type: String,
default: 'label'
},
check: {
type: String,
default: 'visible'
},
active: {
type: Array,
default: () => []
},
keys: {
type: String,
default: ''
},
table:{
type:String,
default: 'tableRef'
}
},
data() {
return {
dataList: [],
checkDataList: [],
isChange:false,
};
},
created() {
},
mounted() {
},
methods: {
handleCheckAll() {
this.dataList.forEach(item => { item[this.check] = true })
this.checkDataList = [...this.dataList]
// const isAllChecked = this.dataList.every(item => item.checkbox)
// this.dataList.forEach(item => {
// item.checkbox = isAllChecked ? false : true
// })
// if (isAllChecked) this.checkDataList = []
// else this.checkDataList = [...this.dataList]
},
// 清空
handleClear() {
this.checkDataList = []
this.dataList.forEach(item => { item[this.check] = false })
},
handlecheckItem(item, index) {
this.dataList[index][this.check] = item[this.check]
this.$forceUpdate()
let findIndex = this.checkDataList.findIndex(items => items[this.value] == item[this.value])
if (item[this.check] && findIndex < 0) {
this.checkDataList.push(item)
} else {
this.checkDataList.splice(findIndex, 1)
}
},
handleMoveRight() {
let arr = this.dataList.filter(item => item[this.check])
this.checkDataList = arr
},
handleDel(item, index) {
this.checkDataList = this.checkDataList.filter(items => items[this.value] != item[this.value])
let findIndex = this.dataList.findIndex(items => item[this.value] == items[this.value])
this.$set(this.dataList, findIndex, { ...item, [this.check]: false })
},
handleDefaultSet() {
let { dataList, checkDataList } = this.initDataList(this.active)
this.dataList = dataList
this.checkDataList = checkDataList
},
handleClose() {
this.$emit('update:visible', false)
},
handleSave() {
// console.log("com ELianTableFieldSet save", this.keys)
if (this.checkDataList.length == 0) return this.$message.warning("请选择要显示的字段信息")
let data = {
checkData: this.checkDataList,
allData: this.dataList,
keys: this.keys
}
let keys = cryptoJS.MD5(this.keys).toString()
localStorage.setItem(keys, JSON.stringify(this.checkDataList))
this.$emit('update:active', this.checkDataList)
this.$emit('update:visible', false)
this.$emit('save', data,this.isChange)
console.log("this.$refs.list", this.$parent.$refs[this.table])
if(this.isChange){
}
console.log("com ELianTableFieldSet save",this.$parent)
this.$eventBus.$emit('nextTickRefreshTable')
},
handleChange(e) {
this.isChange = true
console.log('com ELianTableFieldSet handleChange',e)
},
handleStart(e) {
console.log('com ELianTableFieldSet handleStart',e)
},
handleEnd(e) {
console.log('com ELianTableFieldSet handleEnd',e)
},
initDataList(active) {
let newValList = active.map(item => item[this.value])
let tData = JSON.parse(JSON.stringify(this.data))
let tActive = JSON.parse(JSON.stringify(active))
tData = tData.map(item => {
if (newValList.includes(item[this.value])) {
return { ...item, [this.check]: true }
} else {
return { ...item, [this.check]: false }
}
})
return {
dataList: tData,
checkDataList: tActive
}
}
},
computed: {
checkLen() {
return this.checkDataList.length || 0
},
dataLen() {
return this.data.length || 0
}
},
watch: {
active: {
handler(newVal, oldVal) {
if (newVal) {
let { dataList, checkDataList } = this.initDataList(newVal)
this.dataList = dataList
this.checkDataList = checkDataList
} else {
this.dataList = this.data.map(item => ({ ...item, [this.check]: false }))
}
},
immediate: true
}
},
};
</script>
<style scoped lang="scss">
.elian--table-field {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
.elian--table-field-left,
.elian--table-field-right {
width: 36%;
flex: 1;
.elian--table-field-title {
margin: 10px 0;
display: flex;
justify-content: space-between;
cursor: pointer;
padding: 0 2px;
}
}
.elian--table-field-center {
width: 4%;
text-align: center;
.el-icon-arrow-right {
cursor: pointer;
}
}
.elian--table-field-footer {
width: 100%;
height: 52px;
display: flex;
justify-content: space-between;
align-items: center;
.footer-left {
display: flex;
align-items: center;
}
.footer-tips {
display: flex;
margin-left: 20px;
}
}
.elian--table-field-list {
padding: 12px;
box-sizing: border-box;
min-height: 530px;
max-height: 550px;
overflow: auto;
.elian--table-field-list-item {
margin-bottom: 5px;
display: flex;
align-items: center;
.list-item-title {
margin-left: 5px;
}
}
.list-item {
padding: 2px 0;
}
}
}
.title-hover:hover {
color: #409eff;
cursor: pointer;
}
/* 拖拽选中时的颜色 */
.sortable-chosen {
background-color: #409eff !important; /* 浅蓝色 */
border: 1px dashed #1890ff; /* 加个虚线边框 */
}
/* 拖拽中的元素 */
.sortable-drag {
opacity: 0;
background-color: #409eff !important;
}
.drag-handle{
width:13px;
}
</style>
使用方式:
<TableFieldSet :visible.sync="isShowSetDialog" :data="fieldsData"
:active.sync="currentFieldsActive" :check="fieldsCheck" :value="fieldsValue" :label="fieldsLabel"
:keys="fieldsKey" @save="handleSave" table="tableRef" />
需要安装
'vuedraggable' 和 "crypto-js"(可选)