返回

在延迟加载 Vue.js 路由组件时如何优雅显示“加载”动画?

vue.js

延迟加载路由组件时显示“加载”动画

问题

在使用代码分割将 Vue.js 应用程序拆分成块时,用户在访问某些路由时可能会遇到延迟加载的情况。由于异步组件会在路由导航发生之前预先解析,因此无法在解析组件时显示“加载”组件,给用户带来糟糕的体验。

解决方案

尽管异步组件无法在解析时显示“加载”状态,但我们可以利用 Vue.js 路由守卫和过渡组件来实现类似的效果:

使用 Vue.js 路由守卫

路由守卫允许我们拦截路由导航。我们可以使用 beforeEach 导航守卫来检查目标路由是否需要加载异步组件,如果需要,我们可以显示加载动画。

使用 Vue.js 过渡

过渡组件允许我们为元素添加进入和退出动画。我们可以将过渡组件包装在异步组件周围,并为其配置加载动画。

使用 JavaScript 动画库

此外,我们可以使用像 Vue.js 过渡或其他 JavaScript 动画库这样的库来显示加载动画,而无需修改 Vue.js 路由或组件。

代码示例

以下是一个使用 Vue.js 路由守卫和过渡组件实现解决方案的示例:

import { ref } from 'vue'
import { useRouter, onBeforeRouteUpdate } from 'vue-router'

const router = useRouter()
const loading = ref(false)

onBeforeRouteUpdate((to, from, next) => {
  if (to.matched.some((record) => record.meta.async)) {
    loading.value = true
  }
  next()
})

export default {
  setup() {
    return { loading }
  },
  render() {
    return (
      <transition>
        <template v-show="loading">
          <div>加载中...</div>
        </template>
        <router-view v-else />
      </transition>
    )
  },
}

使用 JavaScript 动画库的示例:

import { onBeforeRouteUpdate } from 'vue-router'
import anime from 'animejs'

const loading = document.getElementById('loading')

onBeforeRouteUpdate((to, from, next) => {
  if (to.matched.some((record) => record.meta.async)) {
    loading.style.display = 'block'
    anime({
      targets: loading,
      opacity: 1,
      duration: 500,
    })
  } else {
    anime({
      targets: loading,
      opacity: 0,
      duration: 500,
      complete: () => {
        loading.style.display = 'none'
      },
    })
  }
  next()
})

常见问题解答

1. 如何为特定的路由添加加载动画?

在路由守卫中检查目标路由的 meta.async 属性,如果为 true,则显示加载动画。

2. 可以使用自定义组件作为加载动画吗?

是的,您可以将自定义组件包装在过渡组件中,并将其用作加载动画。

3. 加载动画在什么情况下会消失?

加载动画会在完成目标路由的异步加载后消失。

4. 可以同时显示多个加载动画吗?

如果您在多个异步路由之间导航,可能会同时显示多个加载动画。

5. 如何优化加载动画性能?

使用轻量级的动画库,避免使用复杂的动画,并在必要时使用延迟加载。