先说需求:就是根据后端传过来的数据合成这样的表头,表头不知道有多少个下级(如图所示)
image.png

后端数据如下:

var arr = [
        { name: '1', id: 1, parentId: null },
        { name: '2', id: 2, parentId: null },
        { name: '1-1', id:3, parentId: 1 },
        { name: '1-1-1', id: 4, parentId: 3 },
        { name: '2-1', id: 5, parentId: 2 }
    ]

(这后端好嘛,,竟然还要前端去排序计算下级)

整理数据:

 function filterHeader(obj,pid){
        let arr = obj.filter(function (item) {
            return item.parentId == pid
        })
        arr.map((item) => {
            // 通过父节点ID查询所有子节点
            item.children = filterHeader(obj, item.id)
            return item
        })
        return arr
    }

image.png

好了数据排序后就开始如何生成多级表头了

先定义一个子组件,用于循环children

export default {
    name: "tableColumn",
    props: ["coloumnHeader"],
    methods: {
        renderHeader(col) {
            //jsx不能直接写v-for,v-if之类的东西(起码我这种写法写了不生效).所以要在这函数里面进行循环
            return col.map((item) => {
                return (
                    <el-table-column
                        align="center"
                        prop={item.prop}
                        label={item.label}
                    >
                    {item.children && this.renderHeader(item.children)} 
                    </el-table-column>
                );
            });
        },
    },
    render() {
        //这是jsx页面。不要写template。函数和tem同时存在,render不生效(这个是和mouted同级的)
        return this.renderHeader([this.coloumnHeader]); //这里是props接收来的数据,因为是对象,对象难循环,所以用了[]数组去包裹他
    },
};

{item.children && this.renderHeader(item.children)} 这句的意思是:如果有他下级,那就继续进入方法

好了封装完了。简单易懂的jsx。如果需求要点击事情之类的.你需要写成这种写法
dd9aa0a61e169f24e90ddfd2adbf646.jpg

现在到父组件去引用这个了。

<table-column
v-for="(item,index) in tableHeader"
:key="index"
:coloumn-header="item"
></table-column>

到这里你就可以看到你的多级表头效果了。


yyblog
278 声望3 粉丝

学习中,将平时项目用到的记录在这里