2022-10-27 工作记录--Swiper/React-解决swiper处理动态数据出现样式紊乱、抖动问题

Swiper/React-解决swiper处理动态数据出现样式紊乱、抖动问题

First of all,检查自己在push数据前是否先清空了数组:

  • 已清空,请直接往下看👁👁哦;
  • 未清空,请先清空数组(可查看我的另外一篇文章),再继续往下看👁👁哦~

一、开门见山 ⭐️

图1:【正确样式】✅

在这里插入图片描述

图2:【紊乱样式】❌

在这里插入图片描述

  • 🎀 需求 —— 弹幕式轮播(如上 图1):
    • 1、分为上下两部分,且交错展示;
    • 2、轮播同时开始、速度匀速,且无限循环,即 跑马灯效果🧃;
    • 3、后端每次返的数据是随机的;
  • 🎀 实现方法 —— swiper
    • 1、上下两部分 -> 采用两个swiper,交错展示 -> 给下swiperswiper-container加上padding-left值:
    • 2、轮播同时开始、速度匀速,且无限循环 -> 跑马灯效果🧃,可以查看我的另外一篇文章喔:🌹
      • swiper-实现跑马灯效果swiper6的实现方式与其相同,只是写法不同,具体用法,请往下看哦☺️,我会以swiper6写个案例);
    • 3、由于是动态数据,出现bug描述如下:💥
      • 当进入弹窗/其他页面后,再次返回页面时,这两个swiper会先抖动一下,然后出现样式紊乱问题(如上 图2):
        • 问题整体描述如下动图:👇🏻👇🏻👇🏻

请添加图片描述

二、亡羊补牢 ⭐️

Taking into account what we have discussed above, we may safely arrive at a conclusion that
依据我们在上文中讨论的内容,我们可以得出一个结论:

  • 解决问题的关键就是解决数据更新问题。
So what do we do❓

在组件卸载及销毁之前 清空掉两个swiper里的数据。

举例 🌰
// 在组件卸载及销毁之前 清空掉两个swiper里的数据。
componentWillUnmount() {
  store.setCarouselInfo1([]);
  store.setCarouselInfo2([]);
}

三、柳暗花明又一村 ⭐️

哒哒哒~🌈 最终没有bug的效果如下动图啦:

请添加图片描述

四、小试牛刀 ⭐️

react-swiper6

1、安装swiper6

npm i swiper@6

或者

yarn add swiper@6

2、部分代码

请添加图片描述

app.jsx

// swiper【Autoplay:自动播放 ,Pagination:分页 ,Navigation:标记页数】
import SwiperCore, { Autoplay, Pagination, Navigation } from 'swiper/core';
SwiperCore.use([Autoplay, Pagination, Navigation])

home.jsx

import React from 'react';
import store from '@src/store'; // 引入接口相关数据
import { Swiper, SwiperSlide } from "swiper/react"; // 引入swiper,实现轮播
import 'style-loader!css-loader!swiper/swiper-bundle.css'; // 引入swiper的css

import './home.less';

class Home extends React.Component {

  async componentDidMount() {
    await store.getHomeData(); // 调用接口-首页
  }
  
  // 在组件卸载及销毁之前 清空掉两个swiper里的数据。
  componentWillUnmount() {
    store.setCarouselInfo1([]);
    store.setCarouselInfo2([]);
  }

  render() {
    // carouselInfo1: 上swiper数据, carouselInfo2: 下swiper数据
    const { carouselInfo1, carouselInfo2 } = store;

    return (
      <div className="home">
        {/* 祝福弹幕【swiper-no-swiping: 禁止手动滑动】*/}
        <div className="blessing swiper-no-swiping">
        
          {/* 上swiper */}
          {
            carouselInfo1?.length > 0 &&
            <Swiper
              className="blessingItems blessingTop"
              slidesPerView={1.25}
              speed={3000}
              freeMode={true}
              loop={true}
              autoplay={{
                delay: 0,
              }}
            >
              {
                carouselInfo1?.map((item, index) => {
                  return (
                    <SwiperSlide className="item" key={index}>
                      {/* 用户祝福背景 */}
                      <span className="item_bg i-blessing_bg"></span>
                      {/* 用户祝福文案 */}
                      <div className="item_texts">
                        {/* 用户名称 */}
                        <span className="user_name text-hidden-ellipsis">工行粉丝</span>
                        {/* 祝福语 */}
                        <div className="content text-hidden-ellipsis">送出祝福:{item.prizeName}</div>
                      </div>
                    </SwiperSlide>
                  )
                })
              }
            </Swiper>
          }
          
          {/* 下swiper */}
          {
            carouselInfo2?.length > 0 &&
            <Swiper
              className="blessingItems blessingBottom"
              slidesPerView={0.85}
              speed={3000}
              freeMode={true}
              loop={true}
              autoplay={{
                delay: 0,
              }}
            >
              {
                carouselInfo2?.map((item, index) => {
                  return (
                    <SwiperSlide className="item" key={index}>
                      {/* 用户祝福背景 */}
                      <span className="item_bg i-blessing_bg"></span>
                      {/* 用户祝福文案 */}
                      <div className="item_texts">
                        {/* 用户名称 */}
                        <span className="user_name text-hidden-ellipsis">工行粉丝</span>
                        {/* 祝福语 */}
                        <div className="content text-hidden-ellipsis">送出祝福:{item.prizeName}</div>
                      </div>
                    </SwiperSlide>
                  )
                })
              }
            </Swiper>
          }
          
        </div>
      </div>
    );
  }
}

export default Home;

home.less

/** 实现匀速轮播 */
.swiper-container>.swiper-wrapper {
    -webkit-transition-timing-function: linear;    /*之前是ease-out*/
      -moz-transition-timing-function: linear;
      -ms-transition-timing-function: linear;
      -o-transition-timing-function: linear;
      transition-timing-function: linear;
      margin: 0 auto;
}

store/index.js

import { makeAutoObservable } from 'mobx';
import API from '../api/index';

const store = makeAutoObservable({
  /** 首页 */
  // 上假轮播配置
  carouselInfo1: [],
  setCarouselInfo1(data) {
    this.carouselInfo1 = data;
  },
  // 下假轮播配置
  carouselInfo2: [],
  setCarouselInfo2(data) {
    this.carouselInfo2 = data;
  },
  
  async getHomeData() {
    const { data, success } = await API.getHomeData(); // 调用接口-首页
    if (data && success) {
      	// 处理假轮播数据,分为上下两部分
        this.setCarouselInfo1([]); //【重要】先清空
        this.setCarouselInfo2([]); //【重要】先清空
      	const { carouselInfo } = data; // 假轮播配置
        carouselInfo?.length > 0 &&
          carouselInfo?.forEach((item, index) => {
            if (index % 2 == 0) {
              // 上假轮播展示偶数项
              this.carouselInfo1.push(item);
            } else {
               // 下假轮播展示奇数项
               this.carouselInfo2.push(item);
            }
          })
      }
    }
  },

})
export default store 

请添加图片描述

补充:若还是解决不了滴话,可查看我的另外一篇博文哦~

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小呀小萝卜儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值