Vue3 + Swiper開發輪播列表組件

Vue3 + Swiper開發輪播列表組件

前端開發中,輪播列表的場景並不少見,通常使用Vue+Swiper來實現,上手比較快。

安裝依賴

直接執行npm命令

    npm i swiper

組件編寫

Html模板代碼

    <template>
        <div class="swiper-list-container">
            <!-- 列標題 -->
            <div class="list-title">
                <div class="title" v-for="(item, index) in column" :key="index">
                    <div class="title-name" :style="{width: `${item.width}px`}">
                        {{item.title}}
                    </div>
                </div>
            </div>
            <!-- 內容 -->
            <div class="swiper-container list-content">
                <div class="swiper-wrapper">
                    <div v-for="(item, index) in data" :key="index" class="swiper-slide list-line">
                        <div v-for="val in column" :key="val.key" :style="{ width: `${val.width}px` }" class="item">
                            {{item[val.key]}}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </template>

JS邏輯代碼

    <script>
    import 'swiper/dist/css/swiper.min.css';
    import 'swiper/dist/js/swiper.min';
    import Swiper from 'swiper';
    import { onMounted, reactive } from 'vue';

    export default ({
        props: {
            // 列標題
            column: {
                type: Array,
                default: () => [
                    { title: '姓名', key: 'name', width: 100 },
                    { title: '年齡', key: 'age', width: 100 },
                    { title: '性別', key: 'sex', width: 100 },
                ],
            },
            // 數據
            data: {
                type: Array,
                default: () => [
                    { name: 'Nicholas', age: '18', sex: '男' },
                    { name: 'Hetty', age: '18', sex: '男' },
                    { name: 'Graham', age: '18', sex: '女' },
                    { name: 'Harley', age: '18', sex: '男' },
                    { name: 'Finbar', age: '18', sex: '女' },
                    { name: 'Oliver', age: '18', sex: '男' },
                ],
            },
        },
        setup(props) {
            const data = reactive({
                swipers: null,
            });
            const createSwiper = () => {
                data.swipers = new Swiper('.swiper-container', {
                    height: 150,
                    speed: 2000, // 勻速時間
                    autoplay: {
                        delay: 0,
                        stopOnLastSlide: false,
                        disableOnInteraction: false,
                    },
                    freeMode: true,
                    loop: props.data.length > 5,
                    direction: 'vertical',
                    slidesPerView: 'auto',
                });
            };
            const init = () => {
                if (!data.swipers) {
                    createSwiper();
                } else if ((data.swipers.passedParams.loop === true && props.data.length <= 5)
                    || (data.swipers.passedParams.loop === false && data.listData.length > 5)) {
                    data.swipers.destroy();
                    data.swipers = null;
                    setTimeout(() => {
                        createSwiper();
                    }, 0);
                } else {
                    data.swipers.update();
                }
            };
            onMounted(() => {
                init();
            });
        },
    });
    </script>

SCSS樣式代碼

    <style lang="scss" scoped>
    .swiper-list-container {
    width: 300px;
    height: 185;

    .list-title {
        display: flex;
        justify-content: flex-start;
        width: 100%;
        height: 30px;
        color: #d59701;
        background-color: #1a6975;

        .title-name {
        width: 120px;
        overflow: hidden;
        line-height: 30px;
        text-align: center;
        text-overflow: ellipsis;
        white-space: nowrap;
        }
    }

    .list-content {
        width: 100%;
        height: 150px;
        overflow: hidden;
        background-color: #e9caa6;

        .list-line {
        display: flex;
        flex-direction: row;
        justify-content: flex-start;
        height: 30px;
        line-height: 30px;
        color: #d59701;

        .item {
            overflow: hidden;
            text-align: center;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        }
    }
    }
    </style>

重點講解

  • class swiper-container/swiper-wrappe/swiper-slide依次排序,由此將Swiper的樣式引入到Vue組件中
  • 初始化Swiper,即createSwiper方法中,new Swiper對象時應該和Html中的class名稱相一致,此外如果存在多個場景使用Swiper時,應該將這個class name命名爲不同的名稱
  • 根據接口或者數據更新,要區分創建和更新Swiper兩種場景

Swiper參數介紹

此處僅介紹上述組件中使用到的參數,其他參數請參照官方文檔
https://www.swiper.com.cn/api/index.html

  • height:強制Swiper的高度(px),當你的Swiper在隱藏狀態下初始化時且切換方向爲垂直才用得上。這個參數會使自適應失效
  • speed:切換速度,即slider自動滑動開始到結束的時間(單位ms),也是觸摸滑動時釋放至貼合的時間
  • autoplay:設置爲true啓動自動切換,並使用默認的切換設置
  • freeMode:啓用自由模式功能,默認情況下Swiper 每次滑動時只滑動一個Slide,並且會自動貼合Wrapper。開啓自由模式後,Swiper 會根據慣性滑動可能不止一格且不會貼合
  • loop:設置爲 true 則開啓循環(loop)模式。loop模式:會在原本slide 前後複製若干個slide (默認一個)並在合適的時候切換,讓Swiper看起來像是循環的。複製的slide 上有一些額外的類名代表他是生成的
  • direction:Swiper的滑動方向,可設置爲水平方向切換 horizontal 或垂直方向切換 vertical
  • slidesPerView:設置slider容器能夠同時顯示的slides數量(carousel模式)。可以設置爲數字(可爲小數,小數不可loop),或者 'auto'則自動根據slides的寬度來設定數量

效果展示

avatar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章