vue自定义指令实现适配img

815 阅读1分钟

场景

现在我们需要展示一组图片,容器大小都是132*132。 但是图片大小不知道。这个时候我们会发现,不管怎么设置图片宽高,都会出现图片被拉深变形的。
原始效果: image.png 简单设置一下图片样式,

 ul {
    display: flex;
    flex-wrap: wrap;
    li {
      width: 132px;
      height: 132px;
      overflow: hidden;
      img {
        width: 100%;
        height: 100%;
      }
    }
  }

图片被拉伸变形

image.png

理想情况下:根据图片动态设置,当宽度大于高的时候,设置高度撑满,否则宽度撑满

获取图片的真实宽高

我们要获取图片真实的宽高,而不是css样式的宽高,我们需要使用html5新增的naturalWidth naturalHeight 测试一下,图片真实大小是258320,容器大小是132132

$0.width
132
$0.naturalWidth
258
$0.height
132
$0.naturalHeight
320

vue指令实现

directive.js

import Vue from 'vue'

// 自动根据图片的宽高适配 需要父元素指定宽高
Vue.directive('autoImg', {
  bind: function (el) {
    el.addEventListener('load', function () {
      // 获取图片的原始宽高
      const w = el.naturalWidth
      const h = el.naturalHeight
      // console.log(`img url 加载完毕,w:${w},h:${h}`)
      const box = document.createElement('div')
      box.style.cssText += `
        position: relative;
        width: 100%;
        height:100%;
      `
      // 宽度大于高度,高度撑满。否则宽度撑满
      if (w >= h) {
        el.style.cssText += `
          height:100%;
          width:auto;
          top:50%;
          left:50%;
          transform: translate(-50%,-50%);
          position: absolute;
        `
      } else {
        el.style.cssText += `
        height:auto;
        width:100%;
        top:50%;
        left:50%;
        transform: translate(-50%,-50%);
        position: absolute;
        `
      }
      const parent = el.parentNode
      box.append(el)
      parent.append(box)
    })
  }
})

记得再main.js中引入。 我们来使用一下

<img src="@/assets/22@2x.a4932a2.png" alt="" v-autoImg />

看效果

image.png

注意:img父容器需要指定width和height
借鉴了微博的图片展示,他的展示效果更完美,总是把图片的主要元素呈现出来。这个前端暂时做不到。

image.png