vue的H5页面滑动翻页插件-swiper使用方法

简单实用,可实现H5页面的丝滑翻页,我是在做公司app年度报告功能时使用的(类似网易云个人年终总结那种动画)

参考文档:swiper官网-vue版

一、下载插件

npm install swiper

二、页面中引用(注意是vue模式)

import 'swiper/less';
import { Swiper, SwiperSlide } from 'swiper/vue';

三、使用

<swiper direction="vertical">
  <swiper-slide>页面1</swiper-slide>
  <swiper-slide>页面2</swiper-slide>
  <swiper-slide>页面3</swiper-slide>
</swiper>

  到这里我们的基本效果完成,页面已经可以竖直方向滑动。

四、拓展

1. 实际应用中,每个页面的内容和逻辑可能很多,那么可以把每个页面封装为组件:

// 异步引入组件,减少首屏加载时间
const DemoA = defineAsyncComponent(() => import('./DemoA.vue'));
const DemoB = defineAsyncComponent(() => import('./DemoB.vue'));
const DemoC = defineAsyncComponent(() => import('./DemoC.vue'));
<swiper direction="vertical">
  <swiper-slide>
    <DemoA />
  </swiper-slide>
  <swiper-slide>
    <DemoB />
  </swiper-slide>
  <swiper-slide>
    <DemoC />
  </swiper-slide>
</swiper>

2. 如果某个页面中有动画效果,且需求是:每次滑动到该页面时动效触发,我们可以通过swiper插件提供的v-slot来实现:

<swiper direction="vertical">
  <swiper-slide>
    <DemoA />
  </swiper-slide>
  <swiper-slide>
    <DemoB />
  </swiper-slide>
  <swiper-slide v-slot="{ isActive }">
    <DemoC :is-active="isActive" />
  </swiper-slide>
</swiper>

  在子组件DemoC中接收isActive作为动效是否触发的参数:

<script setup>
/* 页面3-组件DemoC */
const props = defineProps({
  // 是否滑动到当前页面
  isActive: { type: Boolean, default: false },
});
</script>

<template>
  <div class="container">
    <transition enter-active-class="animate__animated animate__backInRight">
      <div v-show="isActive">测试动效文字</div>
    </transition>
  </div>
</template>

<style lang="less" scoped>
.container {
  position: relative;
  height: 100%;
}
</style>

  这里我使用的动效插件是animate.css,参考文档:animate.css官网

3. 如果有一些组件内容很多或引入的文件过大,导致整个滑动效果加载时卡顿,可以使用swiper插件提供的虚拟化加载,我们可以结合动态组件一起使用:

import { Virtual } from 'swiper/modules';

let slideList = ref([
  { name: DemoA, data: '' },
  { name: DemoB, data: '' },
  { name: DemoC, data: '' },
])
<swiper  :modules="[Virtual]" virtual direction="vertical">
  <swiper-slide v-for="(item, index) in slideList" :key="index" v-slot="{ isActive }" 
    :virtual-index="index">
    <!-- 动态组件 -->
    <component :is="item.name" :data="item.data" :is-active="isActive" />
  </swiper-slide>
</swiper>

  即模式设为Virtual,用virtual-index来控制只需要加载当前展示的页面。使用动态组件的好处:某些页面可能在特定条件下不展示,我们可以写入逻辑来控制slideList的数据,这样virtual-index都能对应到正确的下标。

4. 如果有自动跳转到某个页面的需求,例如最后一个页面中有回到第一页的功能(我在年度报告开发中就有最后一页有‘再看一次’按钮),可通过swiper插件提供的回调函数@swiper来实现:

<swiper  :modules="[Virtual]" virtual direction="vertical" @swiper="onSwiper">
  <swiper-slide v-for="(item, index) in slideList" :key="index" v-slot="{ isActive }" :virtual-index="index">
    <!-- 动态组件 -->
    <component :is="item.name" :data="item.data" :is-active="isActive" @jump="onJumpToFirstPage" />
  </swiper-slide>
</swiper>
let mySwiper = ref(null);
const onSwiper = e => {
  // 将swiper实例对象存储起来
  mySwiper.value = e;
};
// 跳转到第一页
const onJumpToFirstPage = () => {
  mySwiper.value.slideTo(0, 0, false);
};

  即调用实例对象中的slideTo方法实现跳转,slideTo方法的三个参数(跳到第几页,时间,是否触发回调函数)

5. 假如要实现每个页面中有个‘向上滑动’提示标,需要考虑最后一个页面中不展示这个标识,而我们使用了swiper虚拟化,此时插件提供的@reachEnd方法是不起作用的,因为此时每一页理论上来说都是最后一页,所以我们只能在最后一个组件中触发方法回调。

最后,贴上整体代码

首页中:

<script setup>
import 'swiper/less';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Virtual } from 'swiper/modules';

// 异步引入组件,减少首屏加载时间
const DemoA = defineAsyncComponent(() => import('./DemoA.vue'));
const DemoB = defineAsyncComponent(() => import('./DemoB.vue'));
const DemoC = defineAsyncComponent(() => import('./DemoC.vue'));

let slideList = ref([
  { name: DemoA, data: '' },
  { name: DemoB, data: '' },
  { name: DemoC, data: '' },
]);

let mySwiper = ref(null);
const onSwiper = e => {
  // 将swiper实例对象存储起来
  mySwiper.value = e;
};

// 跳转到第一页
const onJumpToFirstPage = () => {
  mySwiper.value.slideTo(0, 0, false);
};

// 是否展示'向上滑动'
let isShowSlideUp = ref(true);
// 隐藏图标
const onHideIcon = item => {
  isShowSlideUp.value = false;
};
</script>

<template>
  <div class="swiper-wrap">
    <swiper :modules="[Virtual]" virtual direction="vertical" :height="height" @swiper="onSwiper">
      <swiper-slide v-for="(item, index) in slideList" :key="index" v-slot="{ isActive }" :virtual-index="index">
        <!-- 动态组件 -->
        <component :is="item.name" :data="item.data" :is-active="isActive" @jump="onJumpToFirstPage" @hide="onHideIcon" />
      </swiper-slide>
    </swiper>
    <div v-if="isShowSlideUp" class="slide-tip">
      <img src="../assets/image/slide-icon.png" class="slide-icon" />
      <div class="slide-text">向上滑动</div>
    </div>
  </div>
</template>

<style scoped lang="less">
.swiper-wrap {
  position: relative;
  height: 100%;
  width: 100%;
}
.slide-tip {
  position: absolute;
  bottom: 40px;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 9;
  .slide-icon {
    width: 12px;
    height: 10px;
    margin-bottom: 6px;
    animation: jump 0.3s ease-in infinite alternate;
  }
  .slide-text {
    color: #000;
    font-size: 12px;
  }
}
@keyframes jump {
  from {
    margin-bottom: 6px;
    width: 12px;
    height: 10px;
  }
  to {
    margin-bottom: 12px;
    width: 15px;
    height: 12.5px;
  }
}
</style>

组件3中:

<script setup>
/* 页面3-组件DemoC */
const props = defineProps({
  // 首页传递过来的数据
  data: { type: String, default: '' },
  // 是否滑动到当前页面
  isActive: { type: Boolean, default: false },
});
const emits = defineEmits(['jump', 'hide']);
// 点击'再看一次'
const onClickViewAgain = () => {
  emits('jump');
};
watch(
  () => props.isActive,
  newValue => {
    // 该页面展示时,隐藏底部icon
    newValue && emits('hide');
  }
);
</script>

<template>
  <div class="container">
    <transition enter-active-class="animate__animated animate__backInRight">
      <div v-show="isActive">测试动效文字</div>
    </transition>
    <div @click="onClickViewAgain">再看一次</div>
  </div>
</template>

<style lang="less" scoped>
.container {
  position: relative;
  height: 100%;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值