Vite插件实现骨架屏的核心是在构建阶段或运行时按需注入匹配页面结构的骨架DOM,而非自动导入组件;主流分构建时静态注入和运行时动态挂载两类,受限于平台兼容性、SSR对齐及样式隔离等问题无法全自动。

在 JS(更准确说是基于 Vite 的 Vue/React 项目)中,用插件实现骨架屏,核心思路不是“自动导入组件”,而是在构建阶段或运行时,按需注入与目标页面结构匹配的骨架占位 DOM。Vite 插件本身不直接“自动导入骨架组件”,而是通过拦截 HTML、分析路由、注入脚本或预生成结构来达成效果。
一、Vite 插件实现骨架屏的典型路径
主流方案分两类,适配不同技术栈和平台能力:
-
构建时静态注入:插件扫描
src/pages或路由配置,在构建阶段为每个页面生成对应的骨架 HTML 片段,注入到该页面的<div id="app">内,再配合 CSS 控制显隐。适合 H5 场景,依赖 AST 解析(如@vue/compiler-sfc)或文件约定(如PageName.skeleton.vue)。 -
运行时动态挂载:插件注入一个轻量全局脚本(如
skeleton-loader.js),在router.beforeEach或组件onBeforeMount阶段,根据当前路由匹配预定义的骨架组件(如SkeletonHome、SkeletonUser),动态createApp并挂载到指定容器。Vue3 + Pinia 项目常用此方式,控制粒度高、可响应数据状态。
二、实际可用的插件与关键配置
目前没有官方 Vite 插件统一支持所有场景,但以下组合已在生产项目验证可行:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
vite-plugin-skeleton(社区维护):支持 Vue2/Vue3,需手动为每个路由配置骨架组件路径,插件负责在 HTML 中插入初始化脚本和占位节点。配置示例:
<!-- vite.config.ts -->import { defineConfig } from 'vite'<br> import vue from '@vitejs/plugin-vue'<br> import skeleton from 'vite-plugin-skeleton'<br> export default defineConfig({<br> plugins: [<br> vue(),<br> skeleton({<br> routes: [<br> { path: '/', skeleton: '@/skeletons/HomeSkeleton.vue' },<br> { path: '/user', skeleton: '@/skeletons/UserSkeleton.vue' }<br> ]<br> })<br> ]<br> }) -
手写简易插件:仅需几十行代码即可完成基础注入。例如监听
transformIndexHtml钩子,在<body>底部插入骨架容器和初始化逻辑:export default function vitePluginCustomSkeleton() {<br> return {<br> name: 'vite-plugin-custom-skeleton',<br> transformIndexHtml(html) {<br> return html.replace(`</body>`, `<br> <div id="skeleton-root" style="display:none"></div><br> <script type="module"><br> import { createApp } from 'vue'<br> import Skeleton from './src/skeletons/Default.vue'<br> createApp(Skeleton).mount('#skeleton-root')<br> </script></body>`)<br> }<br> }<br> }
三、为什么不能“全自动”?关键限制要清楚
所谓“自动生成”,受限于技术边界,并非真正零配置:
-
uni-app 不支持:小程序平台无法在构建时解析 SFC AST,也无法运行时注入 DOM 节点,插件生成的骨架在微信/支付宝真机上会失效(报
Cannot read property 'querySelector' of null);只能手动写轻量<view class="skeleton">+v-if控制。 - SSR/服务端渲染冲突:若项目已启用 Vite SSR,骨架屏需和服务端返回的 HTML 结构对齐,否则 hydration 失败。此时建议骨架逻辑后移至客户端激活阶段。
-
样式隔离问题:插件注入的骨架 DOM 默认不在 Vue 组件作用域内,需确保骨架组件使用全局类(如 UnoCSS 的
bg-gray-200 animate-pulse)或<style scoped>外提为<style>。
四、比插件更轻量的替代方案
如果插件引入复杂度高或跨端兼容性差,可退回到更可控的手动模式:
- 在每个页面组件中,用
v-if / v-else切换真实内容与骨架:<template><br> <div v-if="loading"><br> <SkeletonCard /><br> <SkeletonList /><br> </div><br> <div v-else>{{ data }}</div><br> </template> - 封装通用骨架指令(Vue3):
app.directive('skeleton', {<br> mounted(el, binding) {<br> if (binding.value) el.classList.add('skeleton-loading')<br> }<br> }),再配合 CSS 动画类快速启用。

















