vue3.0 + ts + vite 创建的uni-app封装swiper组件

通过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;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44244230/article/details/124975733