在vue中让页面元素跟随视口宽高变化

365 阅读2分钟

先上代码:

<template>
  <div>
    Metpoid created this component.
    <div class="red" :style="{ height: testHeight }">box One</div>
    <div class="blue" :style="{ width: testWidth }">box Two</div>
  </div>
</template>
<script>
// 这个组件是为了测试页面元素随着视口的宽高变化而变化
export default {
  name: 'testViewsHOrW',
  data () {
    return {
      testHeight: '',
      testWidth: ''
    }
  },
  // 在created 中对变量赋值 , 当然你也可以在data里面就对变量直接赋值
  created () {
    this.testHeight = window.innerHeight - 200 + 'px'
    this.testWidth = window.innerWidth - 50 + 'px'
  },
  mounted () {
    const that = this
    window.onresize = that.throttle(function () {
      that.testHeight = window.innerHeight - 200 + 'px'
      that.testWidth = window.innerWidth - 50 + 'px'
    }, 1000)
  },
  methods: {
  // 这是节流函数
  // fn为你想要被节流的函数 , delay为延时的时间
    throttle (fn, delay = 1500) {
      let inThrottle, lastFn, lastTime
      return function () {
        const context = this
        const args = arguments
        if (!inThrottle) {
          fn.apply(context, args)
          lastTime = Date.now()
          inThrottle = true
        } else {
          clearTimeout(lastFn)
          lastFn = setTimeout(function () {
            if (Date.now() - lastTime >= delay) {
              fn.apply(context, args)
              lastTime = Date.now()
            }
          }, Math.max(delay - (Date.now() - lastTime), 0))
        }
      }
    }
  }
}
</script>
<style lang="less" scoped>
.red {
  background-color: red;
  color: #fff;
}
.blue {
  background-color: blue;
  color: #fff;
}
</style>


完整的效果代码我放在上面了,如果你想直接体验一下,可以直接复制去运行

代码浅析

1.要想达到让页面元素随着视口的宽高变化而变化,首先要做的就是能够获取到视口的宽高。

本文中使用的是 window.innerHeight ; window.innerWidth
当然你也可以使用 document.body.clientHeight ; document.documentElement.clientHeight 等等,根据实际情况做出判断, 前端尺寸的获取可以参考:

三大尺寸家族
        1.offset家族 : 获取 “元素自身”  的真实宽高与位置
            offsetWidth/offsetHeight : 获取自身真实宽高 = width + padding*2 + border*2
            offsetLeft/top : 元素自身 左/上 外边框 到 定位父级  左/下 内边框距离
        2.scroll家族 : 获取 “元素内容”   的真实宽高与位置
            scrollWidth/scrollHeight :  获取元素‘内容’的宽高
            scrollLeft/scrollTop : 元素内容 左/上 滚动出去的距离
        3.client家族 : 获取元素‘可视区域’的宽高与位置
            clientWidth/clientHeight : 获取元素‘可视区域’的宽高
            clientLeft/clientTop : 获取元素‘可视区域’的位置(左边框与右边框)
    
     三大家族特点
        (1)获取的是number类型
        (2)只能获取,不能设置
     

或者查看这篇文章# 前端页面中的各种宽高和位置

2.触发事件,使元素的宽高被重新赋值

本文尝试的方法为,在 mounted 中让 window 注册 resize 方法,在这个方法中让元素的宽高被重新赋值,这里要注意的点是,this 的指向。

lil tips:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。\
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,\
这样this的指向才是vm 或 组件实例对象。

3.为window注册事件,这些事件的触发频率都是非常高的,所以要减少频率。

要达到这个效果可以使用函数节流,封装好的节流函数我已经放在上文的代码中了,当然你也可以尝试自己封装一个。