2021.8.10

坑42(css、子元素充满父元素):目标是通过css使html子元素充满父元素。其中,height: 100%需要父元素有高度设置才起效。如下设置即可:

.box {

    width: 100%;

    height: 100%;

}

坑43(el-tree、高度充满父元素):目标是使el-tree元素的高度充满父元素。

普通使用,单个el-tree组件:首先尝试设置height: 100%,无效果,el-tree的高度依然为内容高度。之后外包一层div设置其高度,经过观察设置的背景色发现,外包div可以充满高度,但不会改变el-tree的颜色。于是,对el-tree和div做相同的设置,如下:

<template>

    <div class='treeBox'>

    <el-tree

    :data='data'

    :props='defaultProps'

    @node-click='handleNodeClick'

    class='tree' ></el-tree>

    </div>

</template>



<style>

.tree {

    background-color: lightgray;

    width: 200px;

    height: 100%;

}

.treeBox{

    background-color: lightgray;

    width: 200px;

    height: 100%;

}

</style>

进阶使用,多层包裹:见同篇,坑45(el-tree、高度、css、多层包裹)。

坑44(el-tree、折叠与展开):目标是一个可控制完全折叠/展开状态的el-tree组件。

el-tree组件控制展开与否的方式是控制节点的expanded属性,true展开,false折叠。在非事件方法中访问组件的方式是使用ref获取组件,之后通过treeRef.value.store.nodesMap可以访问所有节点,只要遍历nodesMap中节点expanded属性即可控制el-tree的折叠与展开。

一开始想直接遍历更改nodesMap中节点的值,但nodesMap没有length属性(后来想到方法了,直接for in即可,详见后文)。于是有了以下两种方法。

首先放一下共同代码template部分、treeData等。其中还包括了使用component组件动态加载箭头图标的功能。如下:

<template>

    <div class='treeTitle'>

        选择

        <el-icon :size='16' @click="changeExpandStatus">

            <component :is='expandArrow' />

        </el-icon>

    </div>

    <el-tree

        :data='treeData'

        empty-text='当前暂无可选'

        :highlight-current='true'

        :default-expand-all='expandAllNode'

        :expand-on-click-node='false'

        :props='defaultProps'

        @node-click='handleNodeClick'

        ref='treeRef' >

    </el-tree>

</template>



<script>

import { reactive,ref,toRefs } from 'vue'

export default {

    setup() {

        const state=reactive({

            expandAllNode:true, //是否全部展开,默认值同时传递给el-tree组件的default-expand-all(只能控制初始展开情况),进行初始化

            expandArrow:'arrow-up' //展开箭头图标

        })

        const treeRef=ref(null)

        const treeData=ref([

            {

                label:'一',

               childrenTree:[

                    {

                        label:'1-1'

                    }

                ]

            },{

                label:'二',

               childrenTree:[

                    {

                        label:'2-1',

                       childrenTree:[

                            {

                                label:'2-1-1',

                               childrenTree:[

                                    { label:'2-1-1-1' },

                                    { label:'2-1-1-2' }

                                ]

                            }

                        ]

                    },

                    {

                        label:'2-2'

                    }

                ]

            },

        ])

        const defaultProps={

            children:'childrenTree',//作为子树的对象属性

            label:'label'

        }

        const handleNodeClick=(data,node,com)=>{

            //点击节点,业务代码

            console.log(data,node,com)

        }

        const changeExpandStatus=()=>{

            //详见下方方法一、二

            //这里放的是基本数据变化,仅改变箭头图标,无实际折叠/展开效果

            let nextExpandStatus=!state.expandAllNode

            state.expandAllNode=nextExpandStatus

            state.expandArrow=nextExpandStatus?'arrow-up':'arrow-down'

        }



        return {

            ...toRefs(state),

            treeRef,

            treenData,

            defaultProps,

            handleNodeClick,

            changeExpandStatus

        }

    },

}

</script>

方法一(展开data,通过$treeNodeId获取节点,较费劲,不推荐):参考的是此篇 vue---element el-tree全选、清空、展开、收缩等基本功能总结_maidu_xbd的博客-CSDN博客_el-tree全选 ,它是通过el-tree绑定的data中的数据项的id(同时设置了el-tree属性node-key='id')来进行遍历的,但这只遍历了最外层数据,没有遍历到子数据项,在data为多层情况下无法控制子节点。

于是设置了一个展平函数flat(),针对当前data的结构进行展平。另外,在未配置id属性的情况下,使用$treeNodeId(会自动生成到treeData)来获取唯一标识。相关代码如下:

function flat(obj,arr=[]){

    //配合data结构的展平

    obj.map(data=>{

        arr.push(data)

        if(data.childrenTree){ //配合data的结构,与defaultProps中的设置相同

            flat(data.childrenTree,arr)

        }

    })

    return arr

}

const changeExpandStatus=()=>{

    let flatTreeData=flat(treeData.value)//展平treeData数据

    let nextExpandStatus=!state.expandAllNode

    for(let i=0;i<flatTreeData.length;i++){//遍历展平的数据flatTreeData

        //通过树的$treeNodeId属性,读取nodesMap中对应的节点进行操作

        treeRef.value.store.nodesMap[flatTreeData[i].$treeNodeId].expanded=nextExpandStatus

    }

    state.expandAllNode=nextExpandStatus

    state.expandArrow=nextExpandStatus?'arrow-up':'arrow-down'

}

方法二(for in获取节点,推荐):不用展开treeData,也不用读取$treeNodeId,直接for in遍历nodesMap获取节点。

const changeExpandStatus=()=>{

    let nextExpandStatus=!state.expandAllNode

    for(let nodeIndex in treeRef.value.store.nodesMap){//for in遍历nodesMap

        //读取nodesMap中对应的节点进行操作

        treeRef.value.store.nodesMap[nodeIndex].expanded=nextExpandStatus

    }

    state.expandAllNode=nextExpandStatus

    state.expandArrow=nextExpandStatus?'arrow-up':'arrow-down'

}

坑45(el-tree、高度、css、多层包裹):前传是同篇的坑43(el-tree、高度充满父元素),当时只是简单的使用el-tree组件。现当坑44(el-tree、折叠与展开)为el-tree上方加上相应标题与控制按钮后,其样式也发生了改变。页面结构见下方代码(为清晰起见,一些与当前情况无关的代码去掉了),为方便查看元素大致大小,设置了颜色区分。另外在调用该组件的外部是有高度设置的,此处略。

问题:当el-tree中元素多到超出范围时,可以发现el-tree高度为pageBox的高度,即treeBox会比pageBox多出一节treeTitle的高度。按当前设置el-tree其高度固定,但超出依然显示,另外滚动条会始终显示。

解决方法:在el-tree外包一层el-container组件即可。此时el-tree高度会随其内容动态变化。当其和treeTitle的高度加起来超过treeBox时,才会显示滚动条。代码如下。

<template>
<div class='pageBox'>
    <div class='treeBox'>
        <div class='treeTitle'>
            <text>选择</text>
            <el-icon :size='16'><arrow-up /></el-icon>
        </div>
               <el-container>
            <el-tree
                class='tree'
                :data='treeData'
                :props='defaultProps' >
            </el-tree>
        </el-container>
    </div>
</div>
</template>

<style>
.pageBox{
    background-color: lightgreen;
    width: 100%;
    height: 100%;
}
.treeTitle{
    padding: 10px;
    display:flex;
    align-items: center;
    justify-content: space-between;
}
.tree{
    background-color: lightsteelblue;
    width: 200px;
}
.treeBox{
    background-color: lightseagreen;
    width: 200px;
    height: 100%;
    overflow: auto;
}
</style>

by 莫得感情踩坑机(限定)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐