简体   繁体   English

如何仅在 Vue 完全加载和初始化后运行 VueJS 代码?

[英]How to run VueJS code only after Vue is fully loaded and initialized?

I am working on a Vue component that will be placed on multiple websites via a CMS system.我正在开发一个 Vue 组件,该组件将通过 CMS 系统放置在多个网站上。 The issue I encounter is that even if my js scripts loading order is correct, sometime I get this error:我遇到的问题是,即使我的 js 脚本加载顺序正确,有时我也会收到此错误:

Uncaught ReferenceError: Vue is not defined
    at HTMLDocument.<anonymous>

Vue is loaded via cdn and it's above the component's code. Vue 是通过 cdn 加载的,它位于组件的代码之上。

All the Vue code is run like this:所有的 Vue 代码都是这样运行的:

document.addEventListener("DOMContentLoaded", () => {
  // here is the Vue code
});

I even added a setTimeout() inside the DOMContentLoaded event and still did not do the trick.我什至在 DOMContentLoaded 事件中添加了一个 setTimeout() ,但仍然没有成功。 window.onload = function() did not work either in all cases. window.onload = function()在所有情况下都不起作用。 I still got that error from time to time.我仍然不时收到该错误。 The scripts are loaded in the body.脚本加载到正文中。

Do you have any idea what it can be another approach?你知道它可以是另一种方法吗? I want to be sure that in the moment the Vue code is fired, Vue is loaded and ready to be initialized on the page.我想确保在触发 Vue 代码的那一刻,Vue 已加载并准备好在页面上进行初始化。 Thank you!谢谢!

use vue mounted() to run any code on page load, and updated() to run after any component operations, so a perfect solution would be combining both Roy j and vue lifecycle hooks使用 vue mounted()在页面加载时运行任何代码,并在任何组件操作之后运行updated() ,因此完美的解决方案是结合Roy j和 vue 生命周期钩子

mounted() {
    window.addEventListener('load', () => {
         // run after everything is in-place
    })
},

// 99% using "mounted()" with the code above is enough, 
// but incase its not, you can also hook into "updated()"
//
// keep in mind that any code in here will re-run on each time the DOM change
updated() {
    // run something after dom has changed by vue
}

note that you can omit the window.addEventListener() and it still going to work but it might miss + if you are using something like jquery outerHeight(true) its better to use it inside the window event to make sure you are getting correct values.请注意,您可以省略window.addEventListener()并且它仍然可以工作,但它可能会错过 + 如果您使用类似 jquery outerHeight(true)的东西,最好在窗口事件中使用它以确保您获得正确的值.

Update 1 :更新 1:

instead of window.addEventListener('load') there is also another way by using document.readyState so the above can be而不是window.addEventListener('load')还有另一种方法是使用document.readyState所以上面可以

mounted() {
  document.onreadystatechange = () => { 
    if (document.readyState == "complete") { 
        // run code here
    } 
  }
},

Update 2 :更新 2:

the most reliable way i've found so far would be using debounce on $nextTick , so usage becomes到目前为止我发现的最可靠的方法是在$nextTick上使用debounce ,所以使用变成

import debounce from 'lodash/debounce'

// bad
updated() {
    this.$nextTick(debounce(() => {
        console.log('test') // runs multiple times
    }, 250)) // increase to ur needs
}

// good
updated: debounce(function () {
    this.$nextTick(() => {
        console.log('test') // runs only once
    })
}, 250) // increase to ur needs

when using debounce with updated it gets tricky, so make sure to test it b4 moving on.当使用带更新去抖动时,它会变得很棘手,所以一定要测试它 b4 继续前进。

Update 3 :更新 3:

you may also try MutationObserver你也可以试试MutationObserver

Use the load event to wait until all resources have finished loading:使用load 事件等待所有资源完成加载:

<script>
  window.addEventListener("load", function(event) {
    // here is the Vue code
  });
</script>

Further explanation 进一步说明

DOMContentLoaded is an event fired when the HTML is parsed and rendered and DOM is constructed. DOMContentLoaded是在解析和呈现 HTML 并构造 DOM 时触发的事件。 It is usually fired pretty fast in the lifetime of the app.它通常在应用程序的生命周期内很快被触发。 On the other hand, load is only fired when all the resources (images, stylesheets etc.) are retrieved from the network and available to the browser.另一方面,只有当所有资源(图像、样式表等)都从网络中检索到并可供浏览器使用时,才会触发load

You can also use the load event for a specific script .您还可以对特定脚本使用 load 事件

https://v2.vuejs.org/v2/api/#mounted https://v2.vuejs.org/v2/api/#mounted

this helped me这对我有帮助

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

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

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