vue.js 遇到的一个奇怪的问题,帮忙看看

这是一个router中components的template:

<template>
  <div class="readerView">
    <div id="area"></div>
  </div>
</template>

<script>
  export default {
    name: 'readerView',
    props: {
      bookDetail: Object,
    },
    data () {
      return {
      }
    },
    watch: {
      'bookDetail' : 'display'
    },
    methods: {
      display() {
        var area = document.getElementById("area");
        console.log("in display, area: ", area);
      }
    },
    mounted () {
      var area = document.getElementById("area");
      console.log("in mounted, area: ", area);
    },
  }
</script>

<style>
@import url("../style/basic.css");
.readerView {
  position: absolute;
  width: 100%;
  height: 100%;
}

</style>

在该组件的mounted函数中调用

document.getElementById("area");

可以正常得到该div

display中同样的调用

document.getElementById("area");

结果竟然返回空???

阅读 8.4k
4 个回答

原因就是

watch: {
      'bookDetail' : 'display'
    },

执行的太早了,dom没有渲染完全,改成

watch: {
      bookDetail(){
          setTimeout(()=>{
              this.display()
          },20);
      }
    }

另外为什么不用ref来取dom呢?

display() 方法在哪调用了

放到this.$nextTick中试试

this.$nextTick(() => {
    let area = document.getElementById("area")
    console.log(area)
})

最后,提醒一下,提问题的时候最好把代码贴出来,你你这一大堆文字,谁有时间去理解你的文字是什么意思。

这个components有一个父亲router传递过来的props对象
watch这个对象,如果改变触发methods中的display函数
然后切换到其他router,再切换到这个router,props值改变
在display函数中同样调用

clipboard.png

你的等dom更新后再去操作dom

methods: {
    display () {
      this.$nextTick(() => {
            let area = document.getElementById("area")
            console.log("in display, area: ", area)
      })
    },
    mounted () {
      this.$nextTick(() => {
            let area = document.getElementById("area")
            console.log("in mounted, area: ", area)
      })
    }

试试楼上说的,用this.$nextTick

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题