基础知识
使用ElementPlus封装的组件
Vue3组件封装(setup语法糖)
优点
- 更少、更简洁的代码,不需要使用
return {}暴露变量和方法了,使用组件时不需要主动注册了; - 更好的
Typescript支持,使用纯Typescript声明props和抛出事件,不会再像option api里那么蹩脚了; - 更好的运行时性能;
实现
- 在components下新建Skeleton,index.vue
<script setup lang="ts">
defineProps({
bg: {
type: String,
default: '#efefef'
},
width: {
type: String,
default: '100px'
},
height: {
type: String,
default: '100px'
},
animated: {
type: Boolean,
default: false
}
})
</script>
<template>
<div class="skeleton" :style="{ width, height }" :class="{ shan: animated }">
<div class="block" :style="{ backgroundColor: bg }"></div>
</div>
</template>
<style scoped lang="scss">
.skeleton {
display: inline-block;
position: relative;
overflow: hidden;
vertical-align: middle;
.block {
width: 100%;
height: 100%;
border-radius: 2px;
}
}
.shan {
&::after {
content: "";
position: absolute;
animation: shan 1.5s ease 0s infinite;
top: 0;
width: 50%;
height: 100%;
background: linear-gradient(to left,
rgba(255, 255, 255, 0) 0,
rgba(255, 255, 255, 0.3) 50%,
rgba(255, 255, 255, 0) 100%);
transform:skewX(-45deg);
}
}
@keyframes shan{
0%{
left:-100%;
}
100%{
left:120%;
}
}
</style>
- components下新建index.ts 引入
import Skeleton from './Skeleton/index.vue';
import type { App } from 'vue';
export const componentsPlugin = {
install(app: App<Element>) {
app.component('Skeleton', Skeleton);
}
};
3.全局引入
import { componentsPlugin } from '@/components'
app.use(componentsPlugin)
.mount('#app')
4.组件使用(二次封装)
<script setup lang="ts">
defineProps({
bg: {
type: String,
default: '#efefef'
}
})
</script>
<template>
<div class='home-skeleton'>
<div class="item" v-for="i in 4" :key="i" :style="{ backgroundColor: bg }">
<Skeleton bg="#e4e4e4" width="306px" height="306px" animated />
<Skeleton bg="#e4e4e4" width="200px" height="24px" animated />
<Skeleton bg="#e4e4e4" width="120px" height="22px" animated />
</div>
</div>
</template>
<style scoped lang="scss">
.home-skeleton {
width: 1240px;
height: 406px;
display: flex;
justify-content: space-between;
.item {
width: 306px;
.skeleton~.skeleton {
display: block;
margin: 16px auto 0;
}
}
}
</style>
5.使用示例
<ul class="goods-list" v-if="newList.length">
<li v-for="item in newList" :key="item.id">
<RouterLink :to="`/detail/${item.id}`">
<img :src="item.picture" alt="">
<p class="name">{{ item.name }}</p>
<p class="price">¥{{ item.price }}</p>
</RouterLink>
</li>
</ul>
<HomeSkeleton v-else/>