踩坑记13 css 子元素充满父元素 | el-tree 折叠与展开、高度、滚动条
2021.8.10坑42(css、子元素充满父元素):目标是通过css使html子元素充满父元素。其中,height: 100%需要父元素有高度设置才起效。如下设置即可:.box {width: 100%;height: 100%;}坑43(el-tree、高度充满父元素):目标是使el-tree元素的高度充满父元素。普通使用,单个el-tree组件:首先尝试设置height: 100%,无效果,
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 莫得感情踩坑机(限定)
更多推荐
所有评论(0)