当前位置: 首页 > news >正文

vue中实现css布局

在vue中通过flex布局实现css的s型结构

通过数组截取循环布局,奇数行从左到右,在偶数行从右到左实现s型结构
在这里插入图片描述

主要内容分为三部分

中间内容部分

数据格式

     items: [{nodeList: [1, 2, 3, 4, 5, 6]},{nodeList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, {nodeList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]},{nodeList: [1, 2, 3, 4]}],
<template><a-row class="row" id="row" :class="alignItem(index)" :style="styleRow(index)"><template v-for="(ite,inde) in it"><a-col :xxl="4" :xl="6" :lg="8" :md="12"><div class="lineBg" :style="{height: lineHeight+'px'}":class="{'lineBorderLeft':it.length<row && inde===0 && index!=0  && inde!=it.length-1 && index%2!=0 || (item.nodeList.length===row*index+1 && index % 2 !== 0),'lineBorderRight':(it.length<row && inde==it.length-1 && index%2==0)}"><div class="line-title"><div class="boxGrey">{{ ite }}</div></div></div><template><div class="item"><div>row:{{ row }}<br/>it:{{ it.length }}<br/>index:{{ index }}<br/></div></div></template><!--   半圆的时候设置占位   --><div v-if="!hasRightAngle" :style="{height: lineHeight+'px'}"></div></a-col></template></a-row>
</template>
computed:{styleRow() {return function (index) {if (index > 0) {return {marginTop: !this.hasRightAngle ? `-${this.lineHeight}px` : 0}}}},alignItem() {return function (index) {return index % 2 !== 0 ? 'justify-end' : ''}},
}
两端拼接的直接和半圆处理

linexx-round-r 和 linexx-round-l 代表拐角处的半圆处理
linexx-l和linexx-r两端的直角
可以切换为直角和半圆

    Vue.component('linexx-round-r', {template: `<div class="linexx-body" :style="styleRoundRow(index)"><div class="linexxrRound"v-if="index%2==0 && index!=splitArrayByLength(item.nodeList,row).length-1"><div class="innerxx-inner"></div></div><template v-else><div style="width: 130px" class="linexxr-box" v-if="index<=0 && it.length>=row":style="styleRoundRow(index)"></div><div style="width: 130px" v-else :style="styleRoundRow(index)"></div></template></div>`,props: ['it', 'item', 'index', 'row', "lineHeight"],inject: ['splitArrayByLength'],computed: {styleRoundRow() {return function (index) {if (index > 0) {return {marginTop: `-${this.lineHeight}px`}}}},}})Vue.component('linexx-round-l', {template: `<div class="linexx-body" :style="styleRoundRow(index)"><div class="linexxlRound"v-if="index%2!=0 && index!=splitArrayByLength(item.nodeList,row).length-1"><div class="innelxx-inner"></div></div><template v-else><div style="width: 130px" class="linexxl-box" v-if="index<=0":style="styleRoundRow(index)"></div><div v-else style="width: 130px" :style="styleRoundRow(index)"></div></template></div>`,props: ['it', 'item', 'index', 'row', 'lineHeight'],inject: ['splitArrayByLength'],computed: {styleRoundRow() {return function (index) {if (index > 0) {return {marginTop: `-${this.lineHeight}px`// marginTop: `-17px`}}}},}})Vue.component('linexx-l', {template: `<div class="linexx-body"><div class="linexxl linexxLeft"v-if="index%2!=0 && index!=splitArrayByLength(item.nodeList,row).length-1"></div><template v-else><div class="linexxl-box" v-if=" index%2==0 || it.length===row"></div><div v-else style="width: 25px"></div></template></div>`,props: ['it', 'item', 'index', 'row'],inject: ['splitArrayByLength'],})Vue.component('linexx-r', {template: `<div class="linexx-body"><div class="linexxr linexxRight"v-if="index%2==0 && index!=splitArrayByLength(item.nodeList,row).length-1"></div><template v-else><div class="linexxr-box" v-if=" index%2!=0 || it.length===row" style="width: 25px"></div><div v-else style="width: 25px"></div></template></div>`,props: ['it', 'item', 'index', 'row'],inject: ['splitArrayByLength'],})
顶点处理

判断有点复杂 应该还可以优化优化

<div class="lineBg" :style="{height: lineHeight+'px'}":class="{'lineBorderLeft':it.length<row && inde===0 && index!=0  && inde!=it.length-1 && index%2!=0 || (item.nodeList.length===row*index+1 && index % 2 !== 0),'lineBorderRight':(it.length<row && inde==it.length-1 && index%2==0)}"><div class="line-title"><div class="boxGrey">{{ ite }}</div></div></div>
完整代码
<div id="app"><div class="container-bg"><div class="container" :style="containerStyle"><div class="container-list" v-for="(item,inx) in items"><div class="row-title"><div class="row-title-text">{{ inx }}</div></div><div style="width: 100%" :id="`row${inx}`"><template v-for="(it,index) in splitArrayByLength(item.nodeList,row)"><div style="width: 100%;position: relative;display: flex"><template v-if="hasRightAngle"><linexx-l :it="it" :item="item" :index="index":row="row"></linexx-l></template><template v-else><linexx-round-l :line-height="lineHeight" :it="it" :item="item" :index="index":row="row"></linexx-round-l></template><a-row class="row" id="row" :class="alignItem(index)" :style="styleRow(index)"><template v-for="(ite,inde) in it"><a-col :xxl="4" :xl="6" :lg="8" :md="12"><div class="lineBg" :style="{height: lineHeight+'px'}":class="{'lineBorderLeft':it.length<row && inde===0 && index!=0  && inde!=it.length-1 && index%2!=0 || (item.nodeList.length===row*index+1 && index % 2 !== 0),'lineBorderRight':(it.length<row && inde==it.length-1 && index%2==0)}"><div class="line-title"><div class="boxGrey">{{ ite }}</div></div></div><template><div class="item"><div>row:{{ row }}<br/>it:{{ it.length }}<br/>index:{{ index }}<br/></div></div></template>
<!--                                        --><div v-if="!hasRightAngle" :style="{height: lineHeight+'px'}"></div></a-col></template></a-row><template v-if="hasRightAngle"><linexx-r :it="it" :item="item" :index="index":row="row"></linexx-r></template><template v-else><linexx-round-r :line-height="lineHeight" :it="it" :item="item" :index="index":row="row"></linexx-round-r></template></div></template></div></div></div></div>
</div>

js部分

new Vue({el: '#app',data() {return {hasRightAngle: false,lineHeight: 25,row: 6,hasAcknowledgeAlarm: false,items: [{nodeList: [1, 2, 3, 4, 5, 6]},{nodeList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, {nodeList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]},{nodeList: [1, 2, 3, 4]}],}},provide() {return {splitArrayByLength: this.splitArrayByLength,styleRoundRow: this.styleRoundRow}},computed: {splitArrayByLength() {return function (array, length) {let result = []for (let i = 0; i < array.length; i += length) {let chunk = array.slice(i, i + length)// 反转偶数位置的子数组if ((i / length) % 2 === 1) {chunk = chunk.reverse()}result.push(chunk)}// console.log(result)return result}},alignItem() {return function (index) {return index % 2 !== 0 ? 'justify-end' : ''}},containerStyle() {if (this.hasAcknowledgeAlarm) {return {width: `calc(100% - 280px)`,marginRight: '10px'}} else {return {width: '100%',marginRight: '0'}}},styleRow() {return function (index) {if (index > 0) {return {marginTop: !this.hasRightAngle ? `-${this.lineHeight}px` : 0}}}}},mounted() {this.handleResize()// 监听浏览器窗口window.addEventListener('resize', this.handleResize);},methods: {handleResize() {const bp = window.innerWidth >= 1600 ? 'xxl' :window.innerWidth >= 1200 ? 'xl' :window.innerWidth >= 992 ? 'lg' :window.innerWidth >= 768 ? 'md' : 'sm'let emunRow = {xxl: 4,xl: 6,lg: 8,md: 12,sm: 12}this.row = 24 / emunRow[bp]console.log('handleResize', bp)},}})

css部分

<style lang="less">.container-bg {background: #f2f2f2;}.container {box-sizing: border-box;padding: 20px;width: 100%;background: linear-gradient(to right, #e8e8e8 1px, transparent 1px),linear-gradient(to bottom, #e8e8e8 1px, transparent 1px);background-repeat: repeat;background-size: 50px 50px;overflow-y: auto;}.container-list {display: flex;//background: #f2f2f2;}.lineBg {box-sizing: border-box;height: 25px;background: #bec8d1;width: 100%;border-top: 4px solid #ffffff;border-bottom: 4px solid #ffffff;cursor: pointer;}.boxGrey {max-width: 80%;position: relative;top: -5px;padding: 5px 15px;//background-color: rgba(40, 140, 115, 0.1);background-color: #768997;color: #ffffff;border-radius: 25px;&::before {content: "";position: absolute;left: 0;top: 0;right: 0;bottom: 0;border-radius: 25px;border: 1px solid #768997;clip-path: polygon(calc(50% - 7px) 0, 50% 5px, calc(50% + 7px) 0, 100% 0, 100% 100%, 0 100%, 0 0);}&::after {content: "";position: absolute;/*top: -5px;*/bottom: -4px;left: calc(50% - 5px);width: 8px;height: 8px;/*transform: rotate(135deg);*/transform: rotate(315deg);//border: 1px solid #fc5454;background-color: #768997;clip-path: polygon(0 0, 0 100%, 100% 100%);}}.lineBorderLeft {border-left: 4px solid lawngreen;}.lineBorderRight {border-right: 4px solid rebeccapurple;}.line-title {display: flex;justify-content: space-around;}.row-title {align-self: flex-start;width: 80px;min-width: 80px;background: #ffffff;box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.16);text-align: center;margin-right: 25px;}.row-title-text {box-sizing: border-box;padding: 5px 0;}.row-title-num {background: #fc5454;color: #ffffff;box-sizing: border-box;padding: 3px 0;}.row {display: flex;flex-wrap: wrap;width: calc(100% - 260px);margin-bottom: 10px;position: relative;}.justify-end {justify-content: end;}.item {box-sizing: border-box;text-align: center;min-height: 63px;color: #333333;box-sizing: border-box;padding: 10px 0;margin: 5px 30px;box-shadow: 0px 0px 16px rgba(0, 0, 0, 0.08);cursor: pointer;}.value {margin-bottom: 8px;}.bgGrey {background: #f0f0f0;}.itemBorder {border: 1px solid #666666;}.setWidth {width: 50%}.linexxlRound {display: flex;justify-content: end;align-items: center;box-sizing: border-box;background: #bec8d1;//background: antiquewhite;width: 130px;height: 100%;border-radius: 200px 0 0 200px;border: 4px solid #ffffff;border-right: none;}.innelxx-inner {height: calc(100% - 34px);box-sizing: border-box;width: 105px;background: #f2f2f2;//background: green;border-radius: 200px 0 0 200px;border: 4px solid #ffffff;border-right: none;}.linexxrRound {box-sizing: border-box;background: #bec8d1;//background: antiquewhite;width: 130px;height: 100%;display: flex;justify-content: start;align-items: center;border-radius: 0 200px 200px 0;border: 4px solid #ffffff;border-left: none;.innerxx-inner {height: calc(100% - 34px);box-sizing: border-box;width: 105px;background: #F2F2F2;//background: green;border-radius: 0 200px 200px 0;border: 4px solid #ffffff;border-left: none;}}.linexxr {box-sizing: border-box;width: 25px;height: 100%;background: #bec8d1;border-top: 4px solid #ffffff;border-bottom: none;border-left: none;position: relative;&::after {content: "";position: absolute;top: 17px;left: 0;width: 4px;height: calc(100% - 17px);background: #ffffff;}&::before {content: "";position: absolute;left: 0px;bottom: -4px;width: 100%;height: 4px;background: #bec8d1;z-index: 1;//border-right: 4px solid #ffffff;box-sizing: border-box;border-left: 4px solid #ffffff;}}.linexxr-box {width: 25px;height: 25px;background: #bec8d1;//background: red;border: 4px solid #ffffff;border-left: none;}.linexxl {box-sizing: border-box;width: 25px;height: 100%;background: #bec8d1;border-top: 4px solid #ffffff;border-bottom: none;border-left: none;position: relative;&::after {content: "";position: absolute;top: 17px;right: 0;width: 4px;height: calc(100% - 17px);background: #ffffff;}&::before {content: "";position: absolute;right: 0;bottom: -4px;width: 100%;height: 4px;background: #bec8d1;z-index: 1;border-right: 4px solid #ffffff;box-sizing: border-box;//border-left: 4px solid #ffffff;}}.linexxl-box {width: 25px;height: 25px;box-sizing: border-box;background: #bec8d1;//background: red;border: 4px solid #ffffff;border-right: none;}.linexxRight {border-right: 4px solid #ffffff;}.linexxLeft {border-left: 4px solid #ffffff;border-bottom: none;}</style>

http://www.mrgr.cn/news/56342.html

相关文章:

  • app端文章列表查询-详细教程(上)
  • python的Django的render_to_string函数和render函数的使用
  • ChatTTS在Windows电脑的本地部署与远程生成音频详细实战指南
  • Java实现文件上传功能
  • 每日新闻掌握【2024年10月22日 星期二】
  • Centos7源报错问题
  • 西门子 SMART PLC 扫码串口通讯
  • 【不要离开你的舒适圈】:猛兽才希望你落单,亲人总让你回家,4个维度全面构建舒适圈矩阵
  • Shell重定向输入输出
  • 数据库表的创建
  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)
  • 算法的学习笔记—数组中的逆序对(牛客JZ51)
  • 安全测试概述和用例设计
  • Modbus协议缺陷(Modbus缺陷)(一次性可读取的寄存器数量有限、不支持寄存器位级写入操作)
  • 【C++】踏上C++学习之旅(三):“我“ 与 “引用“ 的浪漫邂逅
  • 每日算法一练:剑指offer——数组篇(3)
  • IO进程_day4
  • HomeAssistant自定义组件学习-【一】
  • 个税自然人扣缴客户端数据的备份与恢复(在那个文件夹)
  • 当小程序学会‘读心术’:表单处理的神秘法则
  • 【西电电路实验】示波器没波形的解决方法
  • hiveserver与beeline
  • eIQ笔记(UI介绍+Loss曲线+OpenART例程)
  • 『 Linux 』HTTPS
  • 在vue项目中如何使用mixins实现代码复用
  • 迪子开了个劝退价。。。