- 两种方法: 1.文中加入组件(繁琐,每个弹窗都要对应有自己的组件) 2.render组件
- 严格说第二种是第一种的优化(文章记录过程)
- 过程: el-table-column :render-header="renderHeader" -> 利用renderHeader创建自定义点击样式和弹窗
基本思路: el-table提供的render-header渲染表头,renderstatus渲染dom节点;maskShowStatus显示弹窗;filtersStatusClick点击响应,发送请求;
伪代码:
template:
<el-table-column label="状态" prop="statusStr" :render-header="renderStatus"></el-table-column>
...
<table-pop :thisObjBox="this" :listData="filterRules.propsStatusData" v-if="renderStatusData.show" :pos="renderStatusData.pos" @filtersData="filtersStatusClick" :hasIndex="renderStatusData.indexTable"></table-pop> thisobjbox: 筛选返回第一页
listdata: 包含初始化数据,筛选列表的
renderStatusData: { // 状态
show: false, // 是否显示弹窗
pos: {}, // 位置
indexTable: '' // 筛选值
},
filtersStatusClick // 链接后台数据
js:
renderStatus (createElement, {column}) {
return createElement(
'div', {
'class': {
'cell-box': true,
'single-active-triangle': this.renderStatusData.indexTable
// 是否有数据,显示激活状态
}
}, [
createElement('span', [column.label]), // 列表头文字
createElement('i', { // 三角样式
'class': {
'icon-top': true
},
on: {
click: this.maskShowStatus // 三角点击 -- 控制弹窗显示位置
}
})
]
)
}
maskShowStatus (event) {
// 数据优化
this.renderStatusData.pos = tool.getMousePos(event)
this.renderStatusData.show = !this.renderStatusData.show
},
<!--tool getmousepos-->
getMousePos (event) { // 弹窗相对窗口的位置
var e = event || window.event
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft
var scrollY = document.documentElement.scrollTop || document.body.scrollTop
var x = e.pageX || e.clientX + scrollX
var y = e.pageY || e.clientY + scrollY
return { 'x': x, 'y': y }
},
第二版 // 不用再template渲染标签 利用el-popover实现弹窗位置
data () {
return {
filterStatusData: [], // 初始化列表数据
chkStatusSelectData: [], // 选中的数据
}
}
// 渲染表头
renderStatus (h, {column}) {
return h(
'div', [
h('span', column.label),
h('el-popover', {
props: {
trigger: 'click',
'visible-arrow':false,
'popper-class': 'filterPopver'
},
},
[
h(selectFilterComponent, { // 自定义不需要引号
props: {
filterData: this.filterStatusData, // 列表数据
chkSelectData: this.chkStatusSelectData,
multiple: true, // 多选
choice: true
},
on: {
filterClick: this.filterChkStatusClick // 点击响应
}
}),
h('span',
{
class: {
triangle: true,
'active-triangle': this.chkStatusSelectData.length
},
slot: 'reference'
})
],
),
]
)
},
列表数据弹窗:
<template>
<div>
<ul v-if="multiple" class="filter-ul">
<li v-for="item in filterData" :key="item.value"><!-- :class="{'selected': chkSelectData.includes(item.value)}" -->
<el-checkbox v-model="checkedAllData" :label="item.value" @change="handleClick(checkedAllData)">
{{item.name}}
</el-checkbox>
</li>
<li class="choice" v-if="choice">
<span class="sort" @click="handleClick(filterData.map(item => item.value))">全选</span>
<span @click="handleClick([])">取消全选</span>
</li>
</ul>
<ul v-else class="filter-ul">
<li v-for="item in filterData" :key="item.value"
:class="{'selected': radSelectData === item.value}"
@click="handleClick(item)">
{{item.name}}
</li>
</ul>
</div>
</template>
<script>
export default {
props: ['multiple', 'filterData', 'chkSelectData', 'radSelectData', 'choice'], // 多选 列表数据 多选值 单选值
data () {
return {
checkedAllData:[],
}
},
methods: {
handleClick (val) {
this.checkedAllData = val
this.$emit('filterClick', val)
},
},
mounted () {
if (this.chkSelectData) {
this.checkedAllData = this.chkSelectData
}
}
}
</script>
<style lang="less" scoped>
.filter-ul{
.selected{
color: #009966;
font-weight: 700;
}
>li{
cursor: pointer;
line-height: 32px;
padding: 0 20px;
&:hover{
background-color: #f5f7fa;
}
}
.choice{
padding-top: 10px;
font-size: 14px;
color: #666;
border-top: 1px solid #ebeef5;
&:hover{
color: #666;
}
> span{
cursor: pointer;
&:hover{
color: #03B189;
}
}
.sort{
margin-right: 10px;
}
}
}
</style>