仅在加载组件后才在 vue-router 中滚动页面

Juh*_*ila 5 vue.js vue-router nuxt.js

根据 vue-router 文档(https://router.vuejs.org/guide/advanced/scroll-behavior.html#async-scrolling),您可以执行“异步滚动”。我有一个单页应用程序,其中页面的高度逐页变化。返回时,我想将页面滚动到用户单击链接的同一位置。

现在,当立即返回时,页面的组件尚未完全加载,并且页面的整体高度不够长。在组件加载之前,滚动到savedPosition只会到达页面底部。

我可以在 nuxt.config.js 中执行此操作

 router: {
    scrollBehavior (to, from, savedPosition) {
      if (savedPosition)
      {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(savedPosition)
          }, 300)
        })
      }
Run Code Online (Sandbox Code Playgroud)

这将等待 300 毫秒,大约在页面高度被解析的时间,然后才向下滚动。但这并不是最佳的。如果组件的加载时间较长怎么办?

如何仅在页面上的组件加载后实现 vue-router 滚动?

我可以监听 vue-router 页面中的事件吗scrollBehavior?我可以以某种方式等待 Vue 生命周期挂钩来触发滚动吗?我可以触发页面高度变化吗?

sof*_*und 3

使用 ResizeObserver API,您可以添加元素高度变化的事件侦听器:

// create an Observer instance to listen to height changes on an object
const resizeObserver = new ResizeObserver(entries => {
    // Check if the height is enough to scroll to that point
    if(entries[0].target.clientHeight >= savedPosition.top + screen.height) {
        // Then resolve to trigger the scroll and disconnect the observer
        resolve(savedPosition);
        resizeObserver.disconnect();
    }
});
// start observing a DOM node
resizeObserver.observe(document.body);
Run Code Online (Sandbox Code Playgroud)

这是一个完整的示例:

scrollBehavior(to, from, savedPosition) {
    return new Promise((resolve, reject) => {
        if(savedPosition) {
            // create an Observer instance
            const resizeObserver = new ResizeObserver(entries => {
                if(entries[0].target.clientHeight >= savedPosition.top + screen.height) {
                    resolve(savedPosition);
                    resizeObserver.disconnect();
                }
            });
            
            // start observing a DOM node
            resizeObserver.observe(document.body);
        } else {
            resolve({ top: 0 });
        }
    });
}
Run Code Online (Sandbox Code Playgroud)