1.实现骨架屏动画CSS
.bee-skeleton {
background: linear-gradient(-45deg, #f1f2f3 25%, #fff 45%, #f1f2f3 65%);
background-size: 400% 100%;
animation: skeleton-loading 2s ease-in-out infinite;
}
@keyframes skeleton-loading {
0% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
2.注册全局自定义指令
// 判断是否加骨架屏的动画效果
function setClassName(el, boolean) {
if (typeof boolean !== 'boolean') return
const classList = [...el.classList]
if (boolean) {
if (classList.includes('bee-skeleton')) return
el.classList.add('bee-skeleton')
} else {
el.classList.remove('bee-skeleton')
}
}
export default {
// 初始时调用
mounted(el, binding) {
setClassName(el, binding.value)
},
// 数据值变化调用
updated(el, binding) {
setClassName(el, binding.value)
},
}
在src/directives/index.js中导入所有自定义指令并注册
import skeleton from './skeleton'
// 汇总自定义指令
const directives = { skeleton }
// 导出自定义指令
export default {
install(app) {
Object.keys(directives).forEach(key => {
// 将每个directive注册到app中
app.directive(key, directives[key])
})
}
}
在src/main.js中导入自定义指令,并全局注册
import directives from '@/directives/index.js'
const app = createApp(App)
// 全局注册
app.use(directives)
app.mount('#app')
3.普通组件内使用
<div style="width: 100%;height: 200px;" v-skeleton="true"></div>
4.若为复杂的样式使用切图放入封装组件使用
封装组件,传入切图
<template>
<div class="skeleton">
<div
:style="{
minWidth: minWidth + 'px',
minHeight: minHeight + 'px',
background: `url(${src}) no-repeat center`,
backgroundSize: 'contain',
}"
></div>
</div>
</template>
<script setup>
defineProps({
minWidth: {
type: Number,
default: 335,
},
minHeight: {
type: Number,
default: 197,
},
src: {
type: String,
default: require("@/assets/radar01.svg"),
},
});
</script>
<style scoped lang='less'>
.skeleton {
width: 100%;
z-index: 3;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
</style>
使用
<template>
<div>
<div class="use-skeleton" v-if="isLoading" v-skeleton="true">
<Skeleton :src="require('@/assets/Skeletion-Pic2.svg')"/>
</div>
<div v-else>
<!-- 加载完成显示.... -->
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import Skeleton from "./SkeletonScreen.vue";
const isLoading = ref(true)
setTimeout(() => {
isLoading.value = false;
}, 3000)
</script>
<style scoped lang='less'>
.use-skeleton {
width: 100%;
height: 181px;
}
</style>