最终要达成的布局
- 页面整体为左右布局
- 左侧内部分为上下布局(上为高度不固定的容器,下部分需要填满左侧栏容器剩余空间)
- 下部分还嵌套分为上下布局(上为高度固定的标题,下部分为可展示超出上下高度可滚动的列表)
代码结构
HTML:
其实结构就如上述 最终布局描述的一样。
类名为class的容器为左侧栏,id为map的容器为右侧主要内容区域。
核心实现为利用flex实现第一层结构的下半部分自动填充剩余部分。
而需要滚动的区域始终需要一个确切高度值,之所以能够实现滚动区域也自适应,是因为滚动区域用绝对定位相对它的父容器——左侧栏下半部分。
左侧栏使用flex布局,query区域不做任何限制,高度可以变化。下半部分query-data部分使用flex-grow: 1使其可以填满左侧栏剩余部分空间。query-data的header为固定高度,所以可滚动区域需使用绝对定位相对query-data容器进行定位(query-data容器需position: relative),top设为header的高度。
核心CSS如下:
.aside {
position: absolute;
left: 0;
height: 100%;
width: 200px;
display: flex;
flex-direction: column;
}
.query-data {
flex-grow: 1;
position: relative;
}
.header {
height: 40px;
}
.data-list {
overflow: auto;
position: absolute;
bottom: 0;
top: 40px;
width: 100%;
}
结语
推荐使用 codesandbox 进行代码预览,并可以自行修改看到效果。
希望这个思路能够帮到有需要的人,现在暂时无法实现这里面的可滚动区域动态变化,毕竟与可滚动区域同级的查询结果标题有仍然是固定高度,尝试过仍适用flex-grow和flex-shrink属性进行动态变化,但无法实现。如果有朋友有思路欢迎评论。
下面贴出完整代码,以方便无法浏览codesandbox的朋友。
<template>
<div class="main-content">
<div class="aside">
<div class="query">
<input
v-for="(item, index) in list"
:key="index"
v-model="item.value"
:placeholder="`第${index + 1}个 iput`"
/>
<div class="func-area">
<button type="primary">查询</button>
<button @click="addInput">添加</button>
</div>
<hr />
</div>
<div class="query-data">
<div class="header">结果列表</div>
<div class="data-list">
<div v-for="item in 100" :key="item">{{ item }}</div>
</div>
</div>
</div>
<div id="map"></div>
</div>
</template>
<script>
export default {
data() {
return {
list: [{ value: "" }],
};
},
methods: {
addInput() {
this.list.push({ value: "" });
},
},
};
</script>
<style lang="scss">
.main-content {
height: 400px;
width: 600px;
border: 2px solid #000;
position: relative;
}
#map {
position: absolute;
left: 200px;
right: 0;
height: 100%;
background-color: green;
}
.aside {
position: absolute;
left: 0;
height: 100%;
width: 200px;
display: flex;
flex-direction: column;
}
.query-data {
flex-grow: 1;
position: relative;
}
.header {
height: 40px;
}
.data-list {
overflow: auto;
position: absolute;
bottom: 0;
top: 40px;
width: 100%;
}
</style>
本文含有隐藏内容,请 开通VIP 后查看