1. 骨架效果
目的:为了在加载过程中等待效果更好,封装骨架屏组件
实现步骤:
-
骨架屏组件需暴露的属性:高、宽、背景颜色,是否启用动画
-
使用插件的方式进行全局注册
<template>
<!-- 骨架屏,就是一个可定制高、宽、背景以及动画的盒子 -->
<div class="xtx-skeleton" :style="{ width, height, backgroundColor: bg }">
<!-- 额外多加一个盒子,在这个盒子上添加伪元素,做绝对定位 -->
<div class="block" :class="{ animate: animated }"></div>
</div>
</template>
<script setup>
defineProps({
width: {
type: String,
default: '100px'
},
height: {
type: String,
default: '100px'
},
bg: {
type: String,
default: '#efefef'
},
animated: {
type: Boolean,
default: true
}
})
</script>
<style lang="less" scoped>
.xtx-skeleton {
position: relative;
display: inline-block;
vertical-align: middle;
overflow: hidden;
border-radius: 2px;
.block {
width: 100%;
height: 100%;
}
.animate {
&::after {
content: '';
// 设置绝对定位,这样动画可以调整left来实现移动的效果
position: absolute;
width: 50%;
height: 100%;
top: 0;
// 使用动画,属性:name duration time-function delay iteration
animation: move 1s ease 0s infinite;
// 线性渐变,配合伪元素做出一个宽度只有盒子一半的图片,这个图片渐变色为黑白黑,向左倾斜45度,配合动画从左往右移动
background-image: linear-gradient(to left,
rgba(255, 255, 255, 0) 0,
rgba(255, 255, 255, 0.3) 50%,
rgba(255, 255, 255, 0) 100%);
transform: skew(45deg);
}
}
}
// 动画:从左到右移动
@keyframes move {
0% {
left: -100%;
}
100% {
left: 120%;
}
}
</style>
2. 封装轮播图组件
基础布局:
<template>
<div class="xtx-carousel" @mouseenter="stopAutoPlay()" @mouseleave="startAutoPlay()">
<!-- banner -->
<ul class="carousel-body">
<template v-if="sliders.length">
<li
v-for="(slider, i) in sliders"
:key="slider.id"
class="carousel-item"
:class="{fade: index === i}"
>
<router-link :to="slider.hrefUrl">
<img :src="slider.imgUrl" alt="">
</router-link>
</li>
</template>
</ul>
<!-- 左右翻页指示器 -->
<a href="javascript:;" class="carousel-btn prev" @click="toggle(-1)">
<i class="iconfont icon-angle-left"></i>
</a>
<a href="javascript:;" class="carousel-btn next" @click="toggle(1)">
<i class="iconfont icon-angle-right"></i>
</a>
<!-- 指示器 -->
<div class="carousel-indicator">
<span
v-for="(slider, i) in sliders"
:key="slider.id"
@click="index=i"
:class="{active: index===i}"
></span>
</div>
</div>
</template>
暴露出轮播图数组、一幅banner的持续时间、是否自动轮播这三个属性,供父组件传入使用
const props = defineProps({
sliders: {
type: Array,
default: []
},
duration: {
type: Number,
default: 2000
},
autoPlay: {
type: Boolean,
default: false
}
})
自动轮播的逻辑:定时器令索引值更新,且在鼠标移入的时候清除定时器,鼠标移出的时候重新开启定时器
// 自动轮播
const index = ref(0)
let timer = null
const autoPlayFn = () => {
clearInterval(timer)
timer = setInterval(() => {
index.value++
if (index.value > props.sliders.length) {
index.value = 0
}
}, props.duration)
}
// 鼠标移入,停止自动轮播
const stopAutoPlay = () => {
if (timer) {
clearInterval(timer)
}
}
// 鼠标移出,如果是要求自动轮播,则开启自动轮播
const startAutoPlay = () => {
if (props.autoPlay && props.sliders.length) {
autoPlayFn()
}
}
// 监听sliders,判断是否要开启自动轮播
watch(() => props.sliders, (newValue) => {
if (newValue.length && props.autoPlay) {
index.value = 0
autoPlayFn()
}
}, {immediate: true})
// 组件销毁时,销毁定时器
onUnmounted(() => {
if (timer) {
clearInterval(timer)
}
})
点击更改轮播图的逻辑:点击上一张就使索引值-1,点击下一张就使索引值+1,判断边界范围
// 点击更改轮播图
const toggle = (step) => {
let newIndex = index.value + step
if (newIndex > props.sliders.length - 1) {
newIndex = 0
}
if (newIndex < 0) {
newIndex = props.sliders.length - 1
}
index.value = newIndex
}
3. Vue插件的使用
-
Vue2的使用插件的方式:导出一个对象,有install函数,默认传入Vue构造函数,install函数内部使用Vue构造函数扩展Vue功能
-
Vue3的使用插件的方式:导出一个对象,有install函数,默认传入了app应用实例,install函数内部使用app实例扩展Vue功能
import XtxSkeleton from './xtx-skeleton.vue'
import XtxCarousel from '@/components/library/xtx-carousel'
export default {
install(app) {
app.component(XtxSkeleton.name, XtxSkeleton)
app.component(XtxCarousel.name, XtxCarousel)
}
}
main.js中,app实例使用use方法就会自动调用install函数,并传入app应用实例
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
import persistedState from 'pinia-persistedstate'
import router from './router'
import 'normalize.css'
import '../src/assets/styles/common.less'
import UI from './components/library'
const store = createPinia()
store.use(
persistedState({
key: 'erabbit-shop',
paths: ['user', 'cart']
})
)
createApp(App).use(router).use(UI).use(store).mount('#app')
标签:02,03,轮播,default,鲜儿,app,props,import,255 From: https://www.cnblogs.com/jzhFlash/p/16634474.html