作用:开发轮播图
// slider.vue
<script setup>
import { ref } from 'vue';
import useSlider from './use-slider'
const { sliders } = defineProps({
sliders: {
type: Array,
default: []
}
})
const rootRef = ref(null)
const { currentPageIndex } = useSlider(rootRef)
</script>
<template>
<div class="slider" ref="rootRef">
<div class="slider-group">
<div
class="slider-page"
v-for="item in sliders"
:key="item.targetId"
>
<a :href="item.link">
<img :src="item.pic"/>
</a>
</div>
</div>
<div class="dots-wrapper">
<span
class="dot"
v-for="(item, index) in sliders"
:key="item.targetId"
:class="{'active': currentPageIndex === index}">
</span>
</div>
</div>
</template>
<style scoped>
.slider {
z-index: 100;
min-height: 1px;
font-size: 0;
touch-action: pan-y;
.slider-group {
position: relative;
overflow: hidden;
white-space: nowrap;
.slider-page {
background-color: black;
border-radius: 20px;
display: inline-block;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
a {
border-radius: 12px;
display: block;
width: 100%;
}
img {
display: block;
width: 100%;
}
}
}
.dots-wrapper {
position: absolute;
left: 50%;
bottom: 12px;
line-height: 12px;
transform: translateX(-50%);
.dot {
display: inline-block;
margin: 0 4px;
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
&.active {
width: 20px;
border-radius: 5px;
background: rgba(255, 255, 255, 0.8)l;
}
}
}
}
</style>
// use-slider.js
import BScroll from '@better-scroll/core'
import Slide from '@better-scroll/slide'
import { onMounted, onUnmounted, onActivated, onDeactivated, ref } from 'vue'
//局部注册组件
BScroll.use(Slide)
export default function useSlider(wrapperRef) {
const slider = ref(null)
const currentPageIndex = ref(0)
onMounted(() => {
const sliderVal = slider.value = new BScroll(wrapperRef.value, {
click: true,
scrollX: true,
scrollY: false,
momentum: false,
bounce: false,
probeType: 2,
slide: true
})
// 获得轮播图页码
sliderVal.on('slideWillChange', (page) => {
currentPageIndex.value = page.pageX
})
})
onUnmounted(() => {
slider.value.destroy()
})
onActivated(() => {
slider.value.enable()
slider.value.refresh()
})
onDeactivated(() => {
slider.value.disable()
})
return {
slider,
currentPageIndex
}
}
3、slider组件使用
// BannerView.vue
<script setup>
import { fetchBannerData } from '@/api/banner.js'
import { useAsync } from '@/use/useAsync.js'
import slider from '@/components/slider/slider.vue';
const { data, pending } = useAsync(
() => fetchBannerData(2).then((v) => v.data.banners.slice(0,9)), [])
</script>
<template>
<div @touchstart.stop class="slider-wrapper tw-rounded-2xl">
<div class="slider-content">
<slider v-if="data.length" :sliders="data"></slider>
</div>
</div>
</template>
<style scoped>
.slider-wrapper {
position: relative;
width: 100%;
height: 0;
padding-top: 40%;
overflow: hidden;
.slider-content {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
</style>