最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue mounted getBoundingClientRect().height but get 0 - Stack Overflow

programmeradmin2浏览0评论

I'm trying to create a Vue ponents instance programmatically and I got some problems.

<!DOCTYPE html>
<html>
  <head>
    <script src=".js"></script>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
      var vm = new Vue({
        data:{
          mes:'hello vue'
        },
        template:'<div>{{mes}}</div>',
        mounted(){
          console.log(this.$el.getBoundingClientRect().height) // get 0
          this.$nextTick(()=>{
            console.log(this.$el.getBoundingClientRect().height) //get height
          })
        }
      }).$mount()
      document.body.appendChild(vm.$el)
    <script>
  </body>
</html>

My question :

  1. According to docs about the Vue lifecycle, the mounted hooks function should be called after " Create vm.$el and replace 'el' with it ". So I just thought the mounted hooks function should be called after document.body append vm.$el . While the fact is that it is called right after vm.$mount()
  2. Why this.$el.getBoundingClientRect().height get 0 if it is not putted in vm.$nextTick function ?
  3. As far as I know, $nextTick function created a microtask, while the browser UI render should be a macro task. So I don't know why we get the correct height if it is in $nextTick function.
    The DOM height should be calculated after it is putted in the page ( I mean document.body.appendChild(vm.$el))?
    I thought microtask get handled before macro task, so even in $nextTick function we shouldn't get the right height. But it did. I wonder why.

I'm trying to create a Vue ponents instance programmatically and I got some problems.

<!DOCTYPE html>
<html>
  <head>
    <script src="http://vuejs/js/vue.js"></script>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
      var vm = new Vue({
        data:{
          mes:'hello vue'
        },
        template:'<div>{{mes}}</div>',
        mounted(){
          console.log(this.$el.getBoundingClientRect().height) // get 0
          this.$nextTick(()=>{
            console.log(this.$el.getBoundingClientRect().height) //get height
          })
        }
      }).$mount()
      document.body.appendChild(vm.$el)
    <script>
  </body>
</html>

My question :

  1. According to docs about the Vue lifecycle, the mounted hooks function should be called after " Create vm.$el and replace 'el' with it ". So I just thought the mounted hooks function should be called after document.body append vm.$el . While the fact is that it is called right after vm.$mount()
  2. Why this.$el.getBoundingClientRect().height get 0 if it is not putted in vm.$nextTick function ?
  3. As far as I know, $nextTick function created a microtask, while the browser UI render should be a macro task. So I don't know why we get the correct height if it is in $nextTick function.
    The DOM height should be calculated after it is putted in the page ( I mean document.body.appendChild(vm.$el))?
    I thought microtask get handled before macro task, so even in $nextTick function we shouldn't get the right height. But it did. I wonder why.
Share Improve this question edited Jun 21, 2022 at 20:44 Asef Hossini 7531 gold badge9 silver badges11 bronze badges asked Aug 27, 2019 at 11:03 ArchsxArchsx 1,0223 gold badges14 silver badges22 bronze badges 1
  • 1 vuejs/v2/api/#mounted Note this bit -> If you want to wait until the entire view has been rendered, you can use vm.$nextTick inside of mounted: – Keith Commented Aug 27, 2019 at 11:13
Add a ment  | 

2 Answers 2

Reset to default 3

This part of the mounted API docs might be the explanation (emphasis mine):

Called after the instance has been mounted, where el is replaced by the newly created vm.$el. If the root instance is mounted to an in-document element, vm.$el will also be in-document when mounted is called.

Note that mounted does not guarantee that all child ponents have also been mounted. If you want to wait until the entire view has been rendered, you can use vm.$nextTick inside of mounted

Regarding $nextTick():

Defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update.

So either you have a child ponent or the DOM isn't rendered with you call getBoundingClientRect()

See also Vue - is there any way to tie into render being finished?

The problem is that when you call mount you aren't telling it where to mount the $el. The mounted hook will be called before you get to the document.body.appendChild(vm.$el), whereas the $nextTick will be after.

You shouldn't really be appending $el to the DOM yourself. Instead change your HTML to have a suitable target element:, e.g.:

<body>
    <div id="app"></div>
    <script>

Here I've inserted a <div> as the first child of the <body>, immediately before your <script>, to ensure the element exists before the code inside <script> is run.

Then mount the Vue instance either using el: '#app' or by changing the mount() call to mount('#app').

发布评论

评论列表(0)

  1. 暂无评论