动态布局
动态布局主要表现在两方面:
1、布局本身是非固定的
2、布局的内容是非固定的
引起布局动态变化的因素我们称动态因子,通常情况下,动态因子是css样式,也就是说,通过使用不同的样式以达到动态变更布局的效果。
然后在特殊情况下,动态因子也可以是数据,也就是说,可以根据不同的数据来影响布局的显示从而达到动态的效果。
知识点:grid布局,VUE组件
显示效果
场景一:完整显示3*4布局
场景二:完整显示3*3布局
场景三:3*3布局,左右两列显示,中间不显示
场景三:3*4布局,上下两行显示,中间不显示
实现以上效果,需要用到 grid布局
参考:前端基础知识(grid布局)
在场景三、四中,使用隐藏css样式隐藏不需要显示的数据块
静态实现
先采用静态文件的方式实现
<template>
<div class="main-box">
<div class="box3-4">
<div class="box-div">1</div>
<div class="box-div">2</div>
<div class="box-div">3</div>
<div class="box-div">4</div>
<div class="box-div">5</div>
<div class="box-div">6</div>
<div class="box-div">7</div>
<!--使用null-div样式隐藏-->
<!--<div class="null-div">8</div>-->
<div class="box-div">8</div>
<div class="box-div">9</div>
<div class="box-div">10</div>
<div class="box-div">11</div>
<div class="box-div">12</div>
</div>
</div>
</template>
<style>
.box3-4 {
/*vw是相对视口(viewport)的宽度而定的,长度等于视口宽度的1/100*/
/*vh是相对视口(viewport)的高度而定的,长度等于视口高度的1/100*/
width: 80vw;
height: 100%;
display: grid; /* 开启grid布局*/
grid-template-columns: repeat(4, 25%); /*设置4列,每一列占总宽度的25% */
grid-template-rows: repeat(3, 30%); /*设置3行, 每一行占总宽度的30% */
grid-column-gap: 2vh; /*列间距*/
grid-row-gap: 2vh; /*行间距*/
}
.box-div {
background-color: #34ce57;
display: flex;
/*实现水平居中*/
align-items: center;
/*实现垂直居中*/
justify-content: center;
/*文字大小颜色*/
font-size: 10vh;
color: orange;
}
.null-div {
/*隐藏*/
visibility: hidden
}
.main-box {
/*使内部div居中*/
display: flex;
align-items: center;
justify-content: center;
/*背景颜色*/
background-color: cornsilk;
width: 100vw;
height: 80vh;
}
</style>
说明:
1、顶层div居中显示
2、二级子项div使用display: grid布局方式
3、三级子项div对每个方块进行样式填充
这里的关键是二级子项div,通过对grid的设置,子项排布成几行几列,以及行列间隔,子项高和宽。
此时得到的显示效果如上图【场景一】
通过对三级子项div使用null-div来进行隐藏,隐藏5到8就得到上图【场景四】的效果
在【场景一】基础上通过变更行列参数成3行3列
grid-template-columns: repeat(4, 25%); /*设置4列,每一列占总宽度的25% */
grid-template-rows: repeat(3, 30%); /*设置3行, 每一行占总宽度的30% */
就得到【场景二】
再将2,5,8div隐藏就得到【场景三】
以上 的手法是手动设置css样式达到动态布局的效果,接下来在此基础上,改造成动态实现方式。
动态布局
先看效果
因为篇幅有限,这里用按钮模拟数据变更,以此带来布局以及布局显示内容的变更。
实现分三个部分
1、页面入口,包括数据的组织,封装,然后传入子组件【数据预处理】
2、动态布局组件,包括布局定义与判断使用的具体布局,通过数据的行列决定用哪个布局【布局】
3、数据块显示组件,通过判断数据的显示标志,选择需要显示或者隐藏【数据展示】
我们简单的模型,这三部分对应三个wue文件
MyDyGridView.vue
/**
* 页面入口
* 组织数据,传入子组件
*/
<template>
<button class="button-box" @click="change3_3" >场景一</button>
<button class="button-box" @click="change3_4" >场景二</button>
<button class="button-box" @click="change3_2" >场景三</button>
<button class="button-box" @click="change2_4" >场景四</button>
<div class="main-box">
<MyDyGridCom ref="MyDyGridCom" :gridDate="gridDate"></MyDyGridCom>
</div>
</template>
<script>
import MyDyGridCom from '@/components/MyDyGridCom.vue';
export default {
name: 'MyGridView',
components: {
MyDyGridCom,
},
data() {
return {
gridDate: {
/*实际应用中,这些数据可以来自后台接口,从而达到项目级别的动态效果*/
/*行列*/
row: 3,
column: 4,
/*数据下标,数据内容*/
divDateList: [
{index: 1, date: 1},
{index: 2, date: 2},
{index: 3, date: 3},
{index: 4, date: 4},
{index: 5, date: 5},
{index: 6, date: 6},
{index: 7, date: 7},
{index: 8, date: 8},
{index: 9, date: 9}
]
}
};
},
methods: {
change3_3() {
this.showmode = true;
this.gridDate.column = 3;
this.gridDate.divDateList = [
{index: 1, date: 1},
{index: 2, date: 2},
{index: 3, date: 3},
{index: 4, date: 4},
{index: 5, date: 5},
{index: 6, date: 6},
{index: 7, date: 7},
{index: 8, date: 8},
{index: 9, date: 9}
]
},
change3_4() {
this.gridDate.column = 4;
this.gridDate.divDateList = [
{index: 1, date: 1},
{index: 2, date: 2},
{index: 3, date: 3},
{index: 4, date: 4},
{index: 5, date: 5},
{index: 6, date: 6},
{index: 7, date: 7},
{index: 8, date: 8},
{index: 9, date: 9},
{index: 10, date: 10},
{index: 11, date: 11},
{index: 12, date: 12}
]
},
change3_2() {
this.gridDate.column = 3;
this.gridDate.divDateList = [
{index: 1, date: 1},
{index: 2, date: 0},
{index: 3, date: 3},
{index: 4, date: 4},
{index: 5, date: 0},
{index: 6, date: 6},
{index: 7, date: 7},
{index: 8, date: 0},
{index: 9, date: 9}
]
},
change2_4() {
this.gridDate.column = 4;
this.gridDate.divDateList = [
{index: 1, date: 1},
{index: 2, date: 2},
{index: 3, date: 3},
{index: 4, date: 4},
{index: 5, date: 0},
{index: 6, date: 0},
{index: 7, date: 0},
{index: 8, date: 0},
{index: 9, date: 9},
{index: 10, date: 10},
{index: 11, date: 11},
{index: 12, date: 12}
]
},
},
}
</script>
<style>
.main-box {
/*使内部div居中*/
display: flex;
align-items: center;
justify-content: center;
/*背景颜色*/
background-color: cornsilk;
width: 100vw;
height: 80vh;
}
.button-box {
margin-bottom: 2vh;
width: 6vw;
margin-right: 5px;
color: red;
}
.active{
color: red;
}
</style>
MyDyGridCom.vue
/**
* 动态布局组件,布局定义与判断使用的具体布局
* 通过数据的行列决定用哪个布局
*/
<template>
<div class="main-box">
<!--3行3列-->
<div v-if="this.gridDate.row==3 && this.gridDate.column==3" class="box3-3">
<div v-for="(item,index) in this.gridDate.divDateList" :key="index">
<MyDyGridItemCom :item="item"></MyDyGridItemCom>
</div>
</div>
<!--3行4列-->
<div v-if="this.gridDate.row==3 && this.gridDate.column==4" class="box3-4">
<div v-for="(item,index) in this.gridDate.divDateList" :key="index">
<MyDyGridItemCom :item="item"></MyDyGridItemCom>
</div>
</div>
</div>
</template>
<script>
import MyDyGridItemCom from './MyDyGridItemCom';
export default {
props: {
// 数据,包含显示,行列参数
gridDate:{}
},
components: {
MyDyGridItemCom,
},
}
</script>
<style>
.box3-4 {
/*vw是相对视口(viewport)的宽度而定的,长度等于视口宽度的1/100*/
/*vh是相对视口(viewport)的高度而定的,长度等于视口高度的1/100*/
width: 80vw;
height: 100%;
display: grid; /* 开启grid布局*/
grid-template-columns: repeat(4, 25%); /*设置4列,每一列占总宽度的25% */
grid-template-rows: repeat(3, 30%); /*设置3行, 每一行占总宽度的30% */
grid-column-gap: 2vh; /*列间距*/
grid-row-gap: 2vh; /*行间距*/
}
.box3-3 {
/*vw是相对视口(viewport)的宽度而定的,长度等于视口宽度的1/100*/
/*vh是相对视口(viewport)的高度而定的,长度等于视口高度的1/100*/
width: 80vw;
height: 100%;
display: grid; /* 开启grid布局*/
grid-template-columns: repeat(3, 33%); /*设置4列,每一列占总宽度的25% */
grid-template-rows: repeat(3, 30%); /*设置3行, 每一行占总宽度的30% */
grid-column-gap: 2vh; /*列间距*/
grid-row-gap: 2vh; /*行间距*/
}
.main-box {
/*使内部div居中*/
display: flex;
align-items: center;
justify-content: center;
/*背景颜色*/
background-color: cornsilk;
width: 100vw;
height: 80vh;
}
</style>
MyDyGridItemCom.vue
/**
* 数据块显示组件
* 通过判断数据的显示标志,选择需要显示或者隐藏
*/
<template>
<div v-if="item.date!=0" class="box-div">{{item.date}}</div>
<!--数据为0,隐藏显示-->
<div v-else class="null-div"></div>
</template>
<script>
export default {
props: {
// 数据
item: {},
},
}
</script>
<style>
.box-div {
height: 100%;
background-color: #34ce57;
display: flex;
/*实现水平居中*/
align-items: center;
/*实现垂直居中*/
justify-content: center;
/*文字大小颜色*/
font-size: 10vh;
color: orange;
}
.null-div {
/*隐藏*/
visibility: hidden
}
</style>
说明:
在整个动态布局中,动态因子就是数据gridDate,里面包含行列参数用于决定显示的行列数,数据部分决定数据块显示与否。这个数据来自后端服务,那样就可以有专门的管理页面进行配置,站在前端的角度,就是动态显示。
这是一个思路,如果需要更多动态参与的部分。比如块大小,颜色,甚至是整体样式都可以按照这个思路去设计。总之,一句话,抽取动态因子,让动态因子可配置,我们就能实现动态化。
–
–
–
完毕
vue专题开篇:vue专题之开发环境与项目搭建【一】