先上效果:

基本实现思路:

  1. 监听浏览器的resize事件,实时获取到浏览器宽度
  2. 设置一个图片的基础高度(例如300px),以此为基准把图片都缩放到这个高度
  3. 把图片依次加入同一行,如果宽度超过浏览器宽度了,开始下一步处理
  4. 把最后一张导致超出宽度的图片弹出,计算该行已有图片的宽度
  5. 根据面积相等原则,计算新的高度(新的高度 = 浏览器宽度 * 基础高度 / 总的宽度 )
  6. 根据新高度和图片原始比例,计算出图片新的宽高
  7. 最后一行不足以铺满屏幕,进行特殊处理

虽然步骤说起来挺简单,但其实实现起来还是有不少坑的,比如说图片计算新的宽高时记得把边距也算上,最后一行因为不满一行需要特殊处理,图片的比例计算等等

完整的代码如下,已加有注释,可直接当一个组件使用,传入的参数格式如下

imgs:[{ id: 1, url:'图片地址', width: '图片宽度', height: '图片高度' }
]
<template><div v-if="newList.length>0"><div class="row" v-for="(row,index) in newList" :key="index" style="min-width:1100px;"><div class="img-box" v-for="img in row" :key="img.id" :style="{'width':img.width,'height':img.height}"><a :href="'detail/'+img.id" target="_blank"><el-image :src="img.url" alt="图片加载失败" :style="{'width':img.width,'height':img.height}" lazy></el-image></el-image></a></div></div></div>
</template><script>
export default {props: ['imgs'],data: function () {return {screenWidth: document.body.clientWidth,imgsData: [], // 实际操作的图片列表timer: null}},mounted () {const self = this// 添加监听浏览器resize事件self.$nextTick(() => {self.screenWidth = document.body.clientWidthwindow.addEventListener('resize', function () {self.throttle(() => {self.screenWidth = document.body.clientWidth}, 100)})})// 转存传过来的props里的imgs数据self.imgsData = self.imgs},watch: {// 监听浏览器宽度screenWidth (val) {this.screenWidth = val// 宽度一旦发生变化就开始重新排列this.realignImgs()}},computed: {newList () {// 接收的参数是baseheight,图片的基础高度return this.realignImgs(300)}},methods: {// 节流throttle (fn, wait, scope) {clearTimeout(this.timer)this.timer = setTimeout(function () {fn.apply(scope)}, wait)},// 处理数据realignImgs (baseheight) {// baseheight是设置的基础高度,后面的高度都是根据这个基础上下浮动的const newList = []// 设定一个浏览器宽度的最低值为1000pxconst screenWidth = Number(this.screenWidth) > 1000 ? Number(this.screenWidth) : 1000// 先把设定的基础高度当作行高const rowHeight = baseheightlet arrRow = []let imgsData = []// 深拷贝转储一下imgsData = JSON.parse(JSON.stringify(this.imgsData))// 循环 计算每个图片的宽度for (let i = 0; i < imgsData.length; i++) {const item = imgsData[i]// 计算图片的宽高比item.ratio = Number(item.width) / Number(item.height)// 新的宽度,算法是比例乘以行高const newWidth = parseInt(item.ratio * rowHeight)item.width = newWidthitem.height = rowHeight// 定义该行图片宽度之和let totalWidth = 0arrRow.push(item)for (let i = 0; i < arrRow.length; i++) {totalWidth += arrRow[i].width}// 如果该行加入的图片宽度大于了该行的宽度// 就需要弹出最后一张图片,并更改前面的图片大小比例if (totalWidth > screenWidth) {// 把最后一张弹出,恢复原来的wholeWidthconst lastImg = arrRow.pop()totalWidth -= lastImg.width// 利用面积相等原则,来计算新的高度const newHeight = screenWidth * rowHeight / totalWidth// 这里是根据一行图片的数量,计算需要留出的边距const marginSpace = (arrRow.length - 1) * 20// 重新计算宽高,占满一行for (let i = 0; i < arrRow.length; i++) {// 最后再把每张图片等比例缩小一点,以留出边距arrRow[i].width = newHeight * arrRow[i].ratio - marginSpacearrRow[i].height = newHeight - (marginSpace / arrRow[i].ratio)}// 放置完毕之前的图片之后,清空该图片队列// 并将上一行溢出的图片 作为下一行的第一张newList.push(arrRow)arrRow = []arrRow.push(lastImg)}}// 单独处理未最后一行// 遍历每一行,把每一行的长度都加起来,这样才能得出最后一行的元素数量let tmp = 0for (let i = 0; i < newList.length; i++) {tmp += newList[i].length}const lastRow = []for (let i = tmp; i < imgsData.length; i++) {// 高度就以设置好的基础高度为基准了imgsData[i].height = rowHeight// 宽度也是按照比例算的imgsData[i].width = imgsData[i].ratio * rowHeightlastRow.push(imgsData[i])}newList.push(lastRow)return newList}}
}
</script><style scoped>
.row {margin-top: 20px;display: flex;justify-content: space-around;
}a {text-align: center;
}.img-box {margin: 0 10px;transition: all 0.5s;
}.img-box>img {transition: all 0.5s;
}.img-box:hover {transform: scale(1.05);
}.img-box:hover>img {transform: scale(1.05);
}</style>

vue木桶布局(图片自适应浏览器宽度排列)的实现方法相关推荐

  1. css图片自适应浏览器宽度

    .logo img { width: auto; display: block; margin: 0 auto; max-width: 100%; 100% ? "100%" : ...

  2. CSS实现自适应浏览器宽度的正方形

    2019独角兽企业重金招聘Python工程师标准>>> CSS实现自适应浏览器宽度的正方形有以下三种方法: 1.方案一:CSS3 vw 单位 CSS3 中新增了一组相对于可视区域百分 ...

  3. Element-ui配合Vue实现走马灯图片自适应效果

    elementUI配合Vue实现走马灯图片自适应效果(等比缩放,使得图片缩小不挤压,放大不拉伸变形) 解决方法的原理:监听屏幕视口大小如果'resize',发生改变了,就获取图片的高度height,然 ...

  4. html图片自适应浏览器高度,css如何高度自适应浏览器高度?

    高度自适应就是高度能跟随浏览器窗口的大小改变而改变,典型的运用在一些后台界面中上面一栏高度固定用作菜单栏或导航栏,下面一栏高度自适应用于显示内容. 在IE7+及chrome.firefox等浏览器中, ...

  5. 图片宽度自适应浏览器宽度

    function fullScreen(){$("#container").css({"width":window.screen.width,"hei ...

  6. css 图片大小自适应div,CSS 图片自适应显示宽度

    这个使用尤其中手机屏幕上最有用. 有喜欢方法: function ReImgSize(){ for (j=0;j { document.images[j].width=(document.images ...

  7. android 控件宽度自适应_Android中让图片自适应控件的大小的方法

    这就需要把.png格式的图片转成.9.png格式,.9.png就是后缀名.在安装Android-SDK时自带了可以把.png格式的图片编辑后保存就变成了.9.png格式.这个文件存放在你所安装的And ...

  8. HTML中使背景图片自适应浏览器大小

    由于<body>标签的图片不能够拉伸, 解决办法: 1.图片不够大,又background属性不能拉伸图片: 2.只能用个div,把其z-index值设为负,并使这个div大小为整个bod ...

  9. web开发入门,css背景图片自适应屏幕宽度

    现如今,我们经常可以看到很多互联网员工都在抱怨,不是说收入低了,就是说工作时间太长.所以我们会见到有不少优秀的互联网员工,只要有机会,要么去一些学校当老师,要么当公务员之类比较稳定的岗位,当然这些能够 ...

最新文章

  1. 2020 ICPC Macau A. Accelerator(期望,计数,分治FFT)(每日一题 21.7.6)
  2. string Format转义大括号
  3. 实例讲解js中的预编译
  4. 《降级论》《按时交作业的学生何以常穿脏袜子》读后感
  5. Oracle编程入门经典 第7章 表
  6. python获取当前文件夹下所有文件名
  7. linux tar压缩包目录,如何在Linux上使用tar命令解压和压缩文件
  8. java画图板代码_java学习小总结——画图板制做(附代码)
  9. Java-大集合拆分为指定大小的小集合
  10. IEPNGFix:Unclickable children of element 解决办法
  11. python常用函数使用方法实例
  12. 好婚姻必定是灵魂佳偶
  13. cocos2d-x3.2对CocoStudio的支持
  14. 为 WE 打 Call!
  15. java fakepath_20140920遇到的问题--JAVA----JS------Tomcat7.0+Onselect灵敏度+fakepath等若干问题...
  16. linux shell写cgi,shell写cgi脚本
  17. python生成中文字符画_python制作字符画
  18. Windows网络活跃点决定使用的优先权
  19. 报错 | SyntaxError: Legacy octal literals are not allowed in strict
  20. 网络优化之net.ipv4.tcp_tw_recycle和tcp_tw_reuse参数

热门文章

  1. 通告功能、公告、消息(站内短信)、通告 (建表思路与功用)
  2. 公告信息mysql_通告(公告),消息(站内短信),提醒的数据库设计
  3. 老师计算机组合照说说,老师朋友圈的说说
  4. Downie 4.2.6 Mac 上视频下载工具
  5. Canvas引入跨域的图片导致toDataURL()报错的问题的解决
  6. 【BZOJ】2021: [Usaco2010 Jan]Cheese Towers(dp)
  7. 收藏一款高效开源的局域网的文件传输神器
  8. JAVA面向对象程序设计--老男孩IT
  9. python基础技巧(三)——tf
  10. heic格式批量转化jpg