简体   繁体   English

Vue - 有什么方法可以绑定渲染完成?

[英]Vue - is there any way to tie into render being finished?

I'm aware of mounted and created being life cycle hooks and have tried them.我知道mountedcreated是生命周期钩子并尝试过它们。 I've also tried using $nextTick within mounted and that does not work to get an accurate render either.我也尝试在 mount 中使用$nextTick ,但这也无法获得准确的渲染。 I am currently trying to access some data out of a dom node after the initial render.我目前正在尝试在初始渲染从 dom 节点访问一些数据。 Here's the pertinent part of my code:这是我的代码的相关部分:

mounted() {
  console.log(this.$el.getBoundingClientRect().top);
},

This is giving me incorrect data.这给了我不正确的数据。 However, using this code:但是,使用此代码:

mounted() {
  setTimeout(() => {
    console.log(this.$el.getBoundingClientRect().top);
  }, 1000)
},

Does net me the correct data.是否为我提供了正确的数据。 The threshold is about ~700-900 ms before I start getting the correct data.在我开始获取正确数据之前,阈值约为 700-900 毫秒。

Question 1问题 1

Why is the lifecycle invoke when everything hasn't fully rendered?当一切都没有完全呈现时,为什么要调用生命周期?

Question 2问题2

Does it have to do with sibling components that haven't quite mounted yet that might be pushing dimensions?它是否与尚未完全安装的兄弟组件有关,可能会推动尺寸?

Question 3问题 3

Is there a solution, an event that I can hook into that basically says, 'everything on the page has rendered'.有没有一个解决方案,一个我可以挂钩的事件基本上说,“页面上的所有内容都已呈现”。

I don't love the setTimeout solution that I came up with for obvious reasons.由于显而易见的原因,我不喜欢我提出的setTimeout解决方案。

Q1: The lifecycle hooks are only concerned about the instance itself and not the rest of the dom. Q1:生命周期钩子只关心实例本身,而不关心 dom 的其余部分。 Hence - the rest of the page can be pending while the component is fully mounted.因此 - 当组件完全安装时,页面的其余部分可能会挂起。

Q2: Same as Q1. Q2:与 Q1 相同。

Q3: You could use this: Q3:你可以使用这个:

document.addEventListener("DOMContentLoaded", function(event) {
    console.log(this.$el.getBoundingClientRect().top);
});

For an more indepth answer: $(document).ready equivalent without jQuery更深入的答案: $(document).ready 没有 jQuery 的等价物

Edit编辑

You should use this instead:你应该改用这个:

window.addEventListener("load", function(event) {
    console.log(this.$el.getBoundingClientRect().top);
});

I forgot about the external resources.我忘记了外部资源。 DOMContentLoaded is fired when the dom is loaded ie. DOMContentLoaded在加载 dom 时触发,即。 html. html。 load is fired after the external resources have been loaded. load在加载外部资源后触发。 Further reading: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload进一步阅读: https ://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload

Due to the fact that things render asynchronously, you may not be able to be sure that the position isn't going to change.由于事物是异步渲染的,您可能无法确定位置不会改变。 You will likely need to get the position every time something updates.每次更新时,您可能都需要获取该位置。 You can do that with a custom directive , whose update function will be called when things update.您可以使用自定义指令来做到这一点,它的update函数将在事物更新时被调用。

Here's a little demo:这是一个小演示:

 new Vue({ el: '#app', data: { ht: 100, top: null }, directives: { bounding(el, binding, vnode) { vnode.context[binding.expression] = el.getBoundingClientRect().top; } }, mounted() { let times = 5; const i = setInterval(() => { this.ht += 10; if (--times < 1) { clearInterval(i); } }, 1000); } });
 <script src="//unpkg.com/vue@latest/dist/vue.js"></script> <div id="app"> <div :style="{height: `${ht}px`}">Hi</div> <div v-bounding="top">{{top}}</div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM