通过vue3.0 + ts + vite 创建uni-app做小程序开发,封装swiper使用
在开发小程序中,本次项目中关于轮播效果的地方较多,每次写小程序都要去找官网,这次自己封装一个长期使用的swiper组件
父组件
html部分
<Swiper :indicatorType="true" nextMargin="50rpx" :data="data.list" @click="swiperClick"
:displayMultipleItems="2" padding="50rpx" :insideStyle="{boxShadow: '5rpx 10rpx 30rpx #ccc'}"
>
<!-- v-slot 用来绑定子组件插槽传过来的参数 -->
<template v-slot="item">
<view class="swiper-slot">{{item.data.text}}</view>
</template>
</Swiper>
父组件
script部分
import { reactive } from "vue";
import { getCurrentInstance } from 'vue';
import Swiper from "@/wxcomponents/swiper/index.vue";
// 假数据
const data = reactive({
list: <any> [
{img: "https://img.yzcdn.cn/vant/apple-1.jpg", text: "文字1"},
{img: "https://img.yzcdn.cn/vant/apple-2.jpg", text: "文字2"},
{img: "https://img.yzcdn.cn/vant/apple-3.jpg", text: "文字3"},
],
});
// 调用swiper单页点击事件,可以做跳转之类的
const swiperClick = (data: any) => {
console.log(data,"::::");
};
子组件 html 部分
<view class="swiper-container">
<swiper class="swiper-container-sw" :style="{width: '100%', height: props.height + 'rpx'}"
:autoplay="autoplay" :circular="circular" :interval="interval" :duration="duration"
:indicator-dots="indicatorDots" :current="data.current" :indicator-color="indicatorColor"
:indicator-active-color="indicatorActiveColor" :previous-margin="previousMargin"
:next-margin="nextMargin" :display-multiple-items="displayMultipleItems"
:vertical="vertical" :easing-function="easingFunction" @change="change"
>
<swiper-item class="swiper-container-item" v-for="(item, index) in (props.data as any)" :key="index"
:style="{padding: props.padding}" @click="click(item, index)"
>
<view class="swiper-container-card" :style="props.insideStyle">
<image :style="{width: '100%', height: props.IH + 'rpx'}" :src="item.img" />
<slot :data="item"></slot>
</view>
</swiper-item>
</swiper>
<view v-if="indicatorType" :style="data.indicator" class="swiper-indicator">{{data.current+1}} / {{props.data.length}}</view>
</view>
子组件 script 部分
<script setup lang="ts">
import { reactive } from "vue";
const props = defineProps({
// 数据
data: {
type: Array,
default: []
},
// 轮播图高度
height: {
type: Number,
default: 500
},
// 轮播图片高度
IH: {
type: Number,
default: 600
},
// 是否自动播放
autoplay: {
type: Boolean,
default: false
},
// 是否循环
circular: {
type: Boolean,
default: false
},
// 轮播时间间隔
interval: {
type: Number,
default: 3000
},
// 滑动动画时长
duration: {
type: Number,
default: 500
},
// 滑动方向是否为纵向
vertical: {
type: Boolean,
default: false
},
// 是否显示面板指示点
indicatorDots: {
type: Boolean,
default: false
},
// 指示点颜色
indicatorColor: {
type: String,
default: '#fff'
},
// 指示点当前颜色
indicatorActiveColor: {
type: String,
default: '#fff'
},
// 当前所在滑块的 index
current: {
type: Number,
default: 0
},
// 前边距,可用于露出前一项的一小部分,接受 px 和 rpx 值
previousMargin: {
type: String,
default: "0rpx"
},
// 后边距,可用于露出后一项的一小部分,接受 px 和 rpx 值
nextMargin: {
type: String,
default: "0rpx"
},
// 同时显示的滑块数量
displayMultipleItems: {
type: Number,
default: 1
},
// 指定 swiper 切换缓动动画类型
easingFunction: {
type: String,
// 值 默认缓动函数 default
// 线性动画 linear
// 缓入动画 easeInCubic
// 缓出动画 easeOutCubic
// 缓入缓出动画 easeInOutCubic
default: "default"
},
// 是否使用数字指示点
indicatorType: {
type: Boolean,
default: false
},
// 指示点距离顶部的距离
indTop: Number,
// 指示器距离左侧的距离
indLeft: Number,
// 指示器距离右侧的距离
indRight: Number,
// 指示器距离底部的距离
indBottom: Number,
// 设置数字指示器颜色
indColor: {
type: String,
default: '#000'
},
// 设置数字指示器背景色
indBgColor: {
type: String,
default: '#ffffffbf'
},
// 设置内容的内边距
padding: {
type: String,
default: '0'
},
// 设置内容样式
insideStyle: {
type: Object,
default: {}
}
});
// 绑定事件
const emit = defineEmits(["click"]);
// 初始值
const data = reactive({
current: 0,
// 数字指示器样式
indicator: {
// 设置距离顶部的距离
top: props.indTop ? props.indTop + 'rpx' : '',
// 设置距离左侧的距离
left: props.indLeft ? props.indLeft + 'rpx' : '',
// 设置距离右侧的距离
right: props.indRight ? props.indRight + 'rpx' : '',
// 设置距离底部的距离
bottom: props.indBottom ? props.indBottom + 'rpx' : '',
// 设置数字指示器颜色
color: props.indColor,
// 设置数字指示器背景色
backgroundColor: props.indBgColor
}
});
// 轮播滚动的下标index
const change = (e: any) => {
data.current = e.detail.current;
};
// 轮播图单页点击事件
const click = (data: any, index: Number) => {
// 向父组件抛出事件和数据
emit("click", { data, index });
};
</script>
子组件 style 部分
<style lang="scss" scoped>
.swiper-container {
width: 100%;
position: relative;
}
.swiper-container-sw {
position: relative;
}
.swiper-container-item {
height: 100%;
box-sizing: border-box;
border: 1px solid red;
}
.swiper-container-card {
height: 100%;
margin: auto;
overflow: hidden;
box-sizing: border-box;
}
.swiper-indicator {
width: 100rpx;
height: 80prx;
text-align: center;
position: absolute;
border-radius: 30rpx;
}