Element Plus骨架屏怎么动态控制显示和隐藏?

码农玉戈 阅读 34

我用Element Plus的Skeleton做加载占位,但不知道怎么在数据加载完后自动隐藏它。试了v-if绑定loading状态,但骨架屏一闪就没了,体验不好。

这是我的代码:

<template>
  <el-skeleton :loading="loading" animated>
    <template #default>
      <p>{{ data.title }}</p>
    </template>
  </el-skeleton>
</template>

<script setup>
const loading = ref(true);
const data = ref({ title: '' });

onMounted(() => {
  setTimeout(() => {
    data.value.title = '加载完成';
    loading.value = false;
  }, 1000);
});
</script>

是不是用法不对?为啥内容还没渲染出来骨架屏就消失了?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
Des.艺天
你的问题在于 loading 和数据更新是同步的,骨架屏消失的瞬间数据可能还没渲染到页面上,导致"一闪而过"变成空白。

解决办法很简单:数据加载完成后,延迟一段时间再关闭骨架屏。

改一下你的代码:

onMounted(() => {
setTimeout(() => {
data.value.title = '加载完成';
// 数据更新后,延迟200-500ms再关闭骨架屏
setTimeout(() => {
loading.value = false;
}, 300);
}, 1000);
});


这样骨架屏会多停留一小段时间,给真实内容足够的渲染时间,体验就顺滑多了。

如果你的数据比较复杂(比如列表),建议用 skeleton 的 count 属性控制占位行数,这样骨架屏和真实内容的视觉过渡更自然:





本质上这是个时序问题,骨架屏的作用是"占位+过渡",关闭时机要等真实内容真正准备好再动手。
点赞
2026-03-12 03:02
Tr° 东霞
你的问题出在状态管理的不同步上。如果你用 v-if 在骨架屏和内容之间硬切,Vue 需要销毁和重建 DOM,这就造成了闪烁。虽然你贴的代码用了插槽,但手动维护一个 loading 变量很容易在数据还没渲染完就切掉了状态。

更优雅的写法是去掉多余的 loading 变量,直接用数据的状态来驱动骨架屏的显示。这样能保证数据到位的一瞬间骨架屏才消失,体验丝滑。

<template>
<el-skeleton :loading="!data.title" animated>
<template #default>
<p>{{ data.title }}</p>
</template>
</el-skeleton>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const data = ref({ title: '' })

onMounted(async () => {
// 模拟异步请求
await new Promise(resolve => setTimeout(resolve, 1000))
data.value.title = '加载完成'
// 这里不需要手动改 loading,数据变了骨架屏自己会退场
})
</script>


这样写逻辑更纯粹,不需要操心 loading 状态什么时候改,数据有了自然就显示内容,避免了中间的空白期。
点赞 2
2026-03-04 15:33