vue getBoundingClientRect 报错

滚动时我需要监听一个区域的距屏幕的高度,这个区域是一个公共组件,监听的事件我是写在组件那里的,我用 ref 和 DOM 的获取方式都试过了,第一次进去或者切换路由进去页面都是报以下的错
图片描述

但是如果在当前页面刷新一次,就不会再报这个错。
我是在mouted后才执行监听的,代码如下:

  methods: {
    _scroll() {
          let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
          let aside = this.$refs.aside;
          let st = aside.getBoundingClientRect().top;
          
          if(st<0){
            aside.style.top = '50px'
            aside.style.left = '5%'
            aside.style.position = 'fixed'
          }else if(scrollTop<450){
             aside.style.top = '0px'
            aside.style.left = '0%'
            aside.style.position = 'absolute'
          }

      },
  },
  mounted(){
    window.addEventListener('scroll',this._scroll,false)
  },
  destroyed(){
    window.removeEventListener('scroll',this._scroll)
  },
从一个页面跳转到当前页面每次滚动都会报错,
但是直接刷新下本页面再滚动就不会报错,
刷新n次都不会报错

之前在站内也有过相似的问题,但是都没有有效的解决方法。
反复执行出错:Cannot read property 'getBoundingClientRect' of undefined

vue的dom元素绑定了ref找不到getBoundingClientRect

最新发现,我打印了获取的dom,发现滚动时不是一直获取不了,而是滚动时有间隔的获取,上一刻获取了,下一刻就获取不到,然后后一个又能获取了,究竟啥回事呢?
我试过把获取的dom改成写在data里,还有computed,created,mounted里都是一样的结果,所以这是滚动事件的原因吗?

阅读 10.3k
3 个回答

问题补充:我已经在destroyed解绑了滚动事件,但是当我跳转到没有用到这个组件的页面时,滚动还是会报错,也就是解绑没效?

可能导致ref不能获取的原因不太明确,
不过解决方式通常是把获取ref的代码转为异步,例如settimeout(f,0)
或者可以把你初始化v-for变量的时机提前到created

新手上路,请多包涵
  this.$nextTick(function () {
    console.log(this.$refs.wrapper.getBoundingClientRect())
  })
  
  放在nectTick里边
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏