首先这个我看element官网还真没发现咋整,没法在table里再塞一行div啥的
不过自己想了个方法,其实动态定个位就好了,其实动态定位,动态大小啥的,在之前那家公司写uniapp的时候还真是写过好多次....各种兼容,动态获取宽高啥啥的,动态设置宽高等等属性 所以这个功能我就也想到了这么整
不多说,看代码
<template>
<div class="mytable">
<!-- @cell-mouse-enter="handleEnter"
@cell-mouse-leave="handleLeave" -->
<!-- @mouseenter.native="handleEnter1"
@mouseleave.native="handleLeave1" -->
<el-table
@cell-mouse-enter="handleEnter"
:data="tableData"
border
style="width: 100%"
>
<el-table-column
:render-header="handleRender"
prop="date"
label="日期"
width="180"
>
<template slot-scope="scope">
<div>{{ scope.row.date }}</div>
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
<el-table-column prop="checked">
<template slot-scope="scope">
<div>
<el-checkbox
@change="handleMyChange"
v-model="scope.row.checked"
></el-checkbox>
</div>
</template>
</el-table-column>
</el-table>
<div
class="b"
@mouseleave="handleLeave1"
:style="{ top: `${typeTop}px`, height: `${typeHeight}px` }"
v-if="typeShow"
>
<div class="b_t" @click="handleNum">123</div>
</div>
<div @click="checkFlag = !checkFlag">切换选中</div>
</div>
<!-- 感觉我只能写一个元素去定位上去了...根据数据....我靠 -->
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
id: 1,
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
type: 'type1',
checked: true,
index: 1
}, {
date: '2016-05-04',
id: 2,
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄',
type: 'type1',
checked: false,
index: 1
}, {
date: '2016-05-01',
id: 3,
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄',
type: 'type1',
checked: true,
index: 1
},
{
date: '2016-05-03',
id: 4,
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄',
type: 'type2',
checked: true,
index: 2
},
{
date: '2016-05-03',
id: 4,
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄',
type: 'type1',
checked: true,
index: 3
},
{
date: '2016-05-03',
id: 4,
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄',
type: 'type1',
checked: true,
index: 4
},
{
date: '2016-05-03',
id: 4,
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄',
type: 'type1',
checked: true,
index: 4
}
],
typeShow: false,
typeTop: 30,
typeHeight: 64,
checkFlag: true,
timer1: null,
timerFlag: true,
currentId: -1
}
},
// 31 80 129
// 49
// 18 66 114
// 48
methods: {
handleEnter(row, column, cell, event) {
// console.log(row, column, cell, event)
// 第一个是根据这个数据再数组中的位置index,算出top是多少
// // let index = this.tableData.findIndex(el => el.id === row.id)
// let index = this.tableData.findIndex(el => {
// if (el.id === row.id) {
// this.currentId = el.id
// }
// return el.id === row.id
// })
// let index = this.tableData.findIndex(el => {
// if (el.id === row.id) {
// this.currentId = el.id
// }
// return el.id === row.id
// })
// 这个框的top应该是由找到的这个模板的第一个决定
let firstStep = 0
if (row.type === 'type1') {
firstStep = this.tableData.findIndex(el => el.index === row.index)
}
// 而这个框的的高度由模板的步骤数量决定
// if (index === 0) {
// this.typeTop = 31
// } else {
// this.typeTop = 49 * index + 31
// }
let stepArr = this.tableData.filter(el => el.index === row.index)
if (firstStep === 0) {
this.typeTop = 30// 这个是初始到第一个表格上边线的框,距离顶部的距离
} else {
this.typeTop = 48 * firstStep + 30 // 48是表格的高度
}
this.typeHeight = (stepArr.length) * 48 + 18// 这个18是上面123的高度,48是表格的高度
// typeTop
// 第二个是是否展示这个框,根据tye
row.type === 'type1' ? this.typeShow = true : this.typeShow = false
// const self = this
// if (this.timerFlag) {
// clearTimeout(this.timer1)
// this.timer1 = setTimeout(() => {
// let index = self.tableData.findIndex(el => el.id === row.id)
// if (index === 0) {
// self.typeTop = 31
// } else {
// self.typeTop = 49 * index + 31
// }
// // typeTop
// // 第二个是是否展示这个框,根据tye
// row.type === 'type1' ? self.typeShow = true : self.typeShow = false
// console.log(1)
// }, 200)
// }
},
// handleLeave(row, column, cell, event) {
// if (this.currentId !== row.id) {
// if (this.typeShow) {
// this.typeShow = false
// }
// }
// this.typeShow = false
// // if (this.typeShow) {
// // this.typeShow = false
// // }
// },
handleEnter1() {
this.typeShow = true
},
handleLeave1() {
this.typeShow = false
},
handleNum() {
console.log(12313123)
},
handleMyChange() {
let flag = this.tableData.every(el => el.checked)
flag ? this.checkFlag = true : this.checkFlag = false
},
handleRender(h, { column, $index }) {
console.log('afsds')
const self = this
// return (
// <div>123</div>
// )
// 外部这个div,如果设置了domProps innerHTML
// 那其数组[]中的元素什么的就不会起作用
// return h('div', {
// domProps: {
// innerHTML: 'bag'
// }
// }, [
// h('span', {
// domProps: {
// innerHTML: 'bag'
// }
// }, []),
// h('span', {
// domProps: {
// innerHTML: 'bag'
// }
// }, [])
// ]
// )
// 可以渲染两个图片
// return h('div', null,
// [
// h('img', {
// domProps: {
// innerHTML: 'bag'
// },
// attrs: {
// src: 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3681880960,455182084&fm=26&gp=0.jpg'
// }
// }, []),
// h('img', {
// domProps: {
// innerHTML: 'bag'
// },
// attrs: {
// src: 'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3681880960,455182084&fm=26&gp=0.jpg'
// }
// }, [])
// ]
// )
// 双向数据绑定控制选中
return h('el-checkbox', {
props: {
value: self.checkFlag
},
// attrs: {
// // 'v-model': self.checkFlag
// value: self.checkFlag
// },
on: {
change: (e) => {
console.log(e)
// if(e){
// this.tableData.map(el=>{
// el.checked=true
// })
// }
self.checkFlag = !self.checkFlag
this.tableData.map(el => {
el.checked = self.checkFlag
})
}
}
}, []
)
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-table {
// background: red;
/deep/.el-table__row {
// background: red !important;
}
}
.mytable {
position: relative;
border: 1px solid pink;
.b {
position: absolute;
left: 0;
// top: 31px;
width: 100%;
border: 1px solid red;
// height: 64px;
box-sizing: border-box;
&_t {
background: #fff;
// pointer-events: none;
}
}
}
</style>
看效果
hover第四个
hover第三个
主要用了element的行的hover事件 @cell-mouse-enter
以及一个布局,一个div relative 包这个一个table一个红框div,红框div没有背景,里面有个123在上面,背景白色,这样上面部分可以挡住其他列,就比较有效果
然后再cell-mouse-enter整个hover事件里,其实我代码里写了注释,不过我还是写下
// 第一个是根据这个数据再数组中的位置index,算出top是多少
// 第二个是是否展示这个框,根据tye
这个需求就实现啦,哈哈哈哈哈哈
有个地方需要注意,就是上面部分点击是针对这个红色盒子,可以点,而红色盒子下面部分需要能够穿透点击到table里的checkbox,操作等按钮
这时候如此做,红色盒子是absolute z-index不设置,红色盒子上面盒子设置relative,z-index:2即可,要比表格高,因为表格内元素接下来会设置1
而表格内部的的那些元素也设置relative z-index:1即可,这样就比红色盒子下面部分层级高,因为红色盒子下面是没有元素的
如此便好
要特别注意一个比较恶心的地方,由于除了enter事件,还要leave事件来离开的时候隐藏,但是用了之后疯狂闪烁.......,期间试过各种方法,阻止捕获,pointer-event:none等等都没解决
最后用了个好方法解决了
方法是把mouseleave绑定在哪个红色框上,就行了,哈哈哈哈哈
跟新了下代码,加了个功能,因为公司业务需要
如果index相同并且属于type2,那么就属于需要被红框框起来的部分,而且根据数量来,具体代码里有注释,就不再赘述
还有个功能是部分部分被框住的元素不能被拖拽,其他元素可以,当然其他元素拖拽也不能影响到这类元素
这个在公司做完了,具体如何实现的,看我这篇博客https://blog.csdn.net/qq_41430522/article/details/114974402,的下面第三点