vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度

需求:

左右两个列表 挨着排列,当左边内容超出滚动条时,换列显示,右边的列表随之移动

效果图:

1.左边数据:10,右边数据:5

2.左边数据:30,右边数据:5 此时:左边数据分两列显示,右边跟着移动

完整代码:

TypeScript 复制代码
<template>
  <div class="layout-padding">
    <div class="layout-padding-auto layout-padding-view" style="overflow: auto">
      <div class="container1">
        <div class="left" ref="leftRef">
          <div v-for="n in leftItems" :key="n" class="item">Left {{ n }}</div>
          <button @click="clickBtn('left')">+</button>
        </div>
        <div class="right" ref="rightRef">
          <div v-for="n in rightItems" :key="n" class="item">Right {{ n }}</div>
          <button @click="clickBtn('right')">+</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {ref, onMounted, onUnmounted} from 'vue'

const leftItems = ref(180)
const rightItems = ref(50)
const leftRef = ref()
const rightRef = ref()

const clickBtn = (type) => {
  if (type == 'left') {
    leftItems.value++
    getData(leftRef.value)
  } else if (type == 'right') {
    rightItems.value++
    getData(rightRef.value)
  }
}
const getData = (ref) => {
  if (!ref) return
  const items = ref.querySelectorAll('.item')
  if (!items.length) return
  const itemHeight = items[0].offsetHeight + 10
  const containerHeight = ref.offsetHeight
  const columns = Math.ceil((items.length + 1) * itemHeight / containerHeight)
  ref.style.width = `${columns * 200}px`
  ref.style['min-width'] = `${columns * 200}px`
}
onMounted(async () => {
  getData(leftRef.value)
  getData(rightRef.value)
});


const updateSize = () => {
  getData(leftRef.value)
  getData(rightRef.value)
}

onMounted(() => {
  window.addEventListener('resize', updateSize)
})

onUnmounted(() => {
  window.removeEventListener('resize', updateSize)
})
</script>

<style scoped>
.container1 {
  display: flex;
  height: 100%;
  overflow: auto;
}

.left, .right {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 10px;
  padding: 10px;
}

.item {
  padding: 10px;
  background: #eee;
  width: 180px;
  min-width: 180px;
}

button {
  margin-top: 10px;
  width: 180px;
}
</style>
相关推荐
再学一点就睡1 小时前
手写 Promise 静态方法:从原理到实现
前端·javascript·面试
再学一点就睡2 小时前
前端必会:Promise 全解析,从原理到实战
前端·javascript·面试
前端工作日常2 小时前
我理解的eslint配置
前端·eslint
前端工作日常3 小时前
项目价值判断的核心标准
前端·程序员
90后的晨仔3 小时前
理解 Vue 的列表渲染:从传统 DOM 到响应式世界的演进
前端·vue.js
OEC小胖胖4 小时前
性能优化(一):时间分片(Time Slicing):让你的应用在高负载下“永不卡顿”的秘密
前端·javascript·性能优化·web
烛阴4 小时前
ABS - Rhomb
前端·webgl
植物系青年4 小时前
10+核心功能点!低代码平台实现不完全指南 🧭(下)
前端·低代码
植物系青年4 小时前
10+核心功能点!低代码平台实现不完全指南 🧭(上)
前端·低代码
小小李程序员4 小时前
JSON.parse解析大整数踩坑
开发语言·javascript·json