vue专题之vue动态布局的实现【六】

动态布局

动态布局主要表现在两方面:
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">

        <!--33-->
        <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>

        <!--34-->
        <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专题之开发环境与项目搭建【一】

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cy谭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值