Vue如何复用加载Spinner模板及对应逻辑以避免重复编码
当然可以实现,以下是几种常用的复用方案,按推荐优先级排序:
方案1:封装通用加载包装组件(最推荐,符合Vue组件复用最佳实践)
你可以直接把加载逻辑封装成一个带插槽的通用组件,不需要高阶组件这么复杂,所有页面直接引入套在内容外面即可。
首先编写通用组件 PageLoaderWrapper.vue:
<template> <template v-if="isLoading"> <Spinner full size="medium" /> </template> <template v-else> <!-- 插槽承载各页面自定义内容 --> <slot /> </template> </template> <script> export default { computed: { isLoading() { return this.$store.getters['loader/isLoading']; }, } } </script>
在任意页面引用使用即可:
<template> <PageLoaderWrapper> <p>Page data</p> <!-- 直接编写当前页面的所有内容即可 --> </PageLoaderWrapper> </template> <script> import PageLoaderWrapper from '@/components/PageLoaderWrapper.vue' export default { components: { PageLoaderWrapper } // 无需重复编写isLoading计算属性 } </script>
该方案侵入性最低,加载逻辑完全收敛在封装组件内,后续需要调整加载样式、判断逻辑时只需要修改一次通用组件即可。
方案2:使用Mixin实现(适合不想修改页面template结构的场景)
如果你不想调整每个页面的template标签内容,也可以把计算属性抽成公共mixin:
首先编写 loader.mixin.js:
export default { computed: { isLoading() { return this.$store.getters['loader/isLoading']; }, } }
页面使用时直接引入mixin,保留原有template判断逻辑即可:
<template> <template v-if="isLoading"> <Spinner full size="medium" /> </template> <template v-else> <p>Page data</p> </template> </template> <script> import loaderMixin from '@/mixins/loader.mixin.js' export default { mixins: [loaderMixin] // 无需重复编写isLoading计算属性 } </script>
注意:如果是Vue3项目更推荐用组合式函数代替mixin,可避免命名冲突、逻辑来源不清晰的问题
方案3:高阶组件实现(符合你最初的设想,Vue场景下使用频次较低)
高阶组件本质是接收一个组件作为参数,返回包装后的新组件,实现方式如下:
编写 withPageLoader.js:
import Spinner from '你的Spinner组件路径' export default function withPageLoader(WrappedComponent) { return { computed: { isLoading() { return this.$store.getters['loader/isLoading']; } }, render(h) { if (this.isLoading) { return h(Spinner, { props: { full: true, size: 'medium' } }) } return h(WrappedComponent, { attrs: this.$attrs, on: this.$listeners }) } } }
页面使用方式:
<template> <p>Page data</p> </template> <script> import withPageLoader from '@/utils/withPageLoader' export default withPageLoader({ // 原页面的组件配置,无需编写任何加载相关逻辑 name: 'YourPage', // 其他页面业务逻辑... }) </script>
内容的提问来源于stack exchange,提问作者Thore
相关产品推荐
相关产品推荐

