欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

react 組件實(shí)現(xiàn)無縫輪播示例詳解

 更新時(shí)間:2022年10月19日 15:44:23   作者:安穩(wěn).  
這篇文章主要為大家介紹了react 組件實(shí)現(xiàn)無縫輪播示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

需求是做一個(gè)無縫輪播圖,我說這不是有很多現(xiàn)成的輪子嗎?后來了解到他有一個(gè)特殊的需求,他要求小圓點(diǎn)需要在輪播圖外面,因?yàn)楝F(xiàn)在大部分插件都是將小圓點(diǎn)寫在輪播圖內(nèi)部的,這對(duì)于不了解插件內(nèi)部結(jié)構(gòu)的小伙伴確實(shí)不知道如何修改。

很久沒有寫插件的我準(zhǔn)備寫一個(gè)插件(react)

無縫輪播

無縫輪播從最后一張到第一張的過程中不會(huì)原路返回,它就像輪子似的,從結(jié)束到開始是無縫連接的,非常自然地循環(huán)下去。

實(shí)現(xiàn)思路

輪播圖的實(shí)現(xiàn)思路有很多,我們這里采用的是最簡單的輪播圖方案,如上圖,即當(dāng)輪播圖輪播到第x張圖片時(shí),當(dāng)前整個(gè)輪播圖列表中只保留第x張圖片,其余圖片dom全部隱藏掉即可。

那么大家有一個(gè)疑問,這樣不會(huì)導(dǎo)致切換時(shí)不連貫嗎?這個(gè)大家不必?fù)?dān)心,我們可以在上一個(gè)輪播圖小時(shí)和下一個(gè)輪播圖展現(xiàn)時(shí)增加動(dòng)畫效果,來達(dá)到連貫的感覺。

構(gòu)思使用時(shí)代碼結(jié)構(gòu)

參考了大部分輪播圖組件,得出來下面的這種使用結(jié)構(gòu)。

import Carousel,{ Item } from '組件'
render(){
    return (
        <Carousel>
            <Item><img src="xxx" /></Item>
            <Item><img src="xxx" /></Item>
            <Item><img src="xxx" /></Item>
        </Carousel>
    )
}

Carousel組件

新建Carousel組件,這個(gè)組件是組件的整體框架文件。

內(nèi)部增加inner div 來充當(dāng)當(dāng)前展示輪播圖的視口

const Carousel=()=>{
    return (
        <div className={'carousel'}>
            <div className={'carousel-inner'}> 
                {xxx輪播圖xxx}
            </div> 
        </div>
    )
} 

overflow:hidden是關(guān)鍵

.inner{
    width:100%;
    height:100%;
    position: relative;
    overflow: hidden;
} 

CarouselItem組件

新建CarouselItem組件,這個(gè)組件是Carousel組件的子組件,是輪播圖列表每一項(xiàng)的容器。

const CarouselItem=(props)=>{ 
    return (
        <div className={'carousel-item'}>
            {props.children}
        </div>
    )
}

注意 這里需要使用top0 left0 不然顯示的時(shí)候會(huì)從上往上偏移 導(dǎo)致錯(cuò)誤顯示

.carousel-item{
    position: absolute;
    left:0;
    top:0;
    width: 100%;
    height:100%; 
}

完善組件

  • 如何顯示當(dāng)前輪播圖元素

之前我們說過這次我們輪播圖的核心思路是顯示當(dāng)前元素,那么什么情況下顯示當(dāng)前元素呢?

carousel組件內(nèi)有一個(gè)state表示當(dāng)前輪播到第幾張圖 我們這里叫current,而根據(jù)傳入carousel的元素排序,我們可以在item內(nèi)部拿到當(dāng)前是第幾張圖片,然后2者如果是相等的,就顯示當(dāng)圖片。

我們?nèi)绾潍@取元素當(dāng)前的index呢?我們可以利用react提供的解析children的api

// util
import React from "react";
export function injecteIndex(children:React.ElementType,current):any{
    let result:React.ReactElement[]=[];
    React.Children.forEach(children,(item,index)=>{
        result.push(React.cloneElement((item as any),{
            //selfIndex即為輪播圖的index
            selfIndex:index,
            key:index,
            current
        }))
    });
    return result;
}
//carousel組件
//initial 為傳入配置 默認(rèn)為0 即默認(rèn)展示第一張圖
const Carousel=()=>{
    const {
        initial
    }=props;
    const [current,setCurrent]=useState<number>(initial);
    return (
        <div className={'carousel'}>
            <div className={'carousel-inner'}> 
                {injecteIndex(children,current)}
            </div> 
        </div>
    )
}  
//carousel-item組件
const CarouselItem=(props)=>{ 
    const { selfIndex,current }=props;
    const visible=selfIndex===current
    return (
        {visible && <div className={'carousel-item'}>
            {props.children}
        </div>}
    )
}
  • 實(shí)現(xiàn)autoPlay

上面我們其實(shí)已經(jīng)實(shí)現(xiàn)了第一張圖的展示,那么我們?nèi)绾巫屗麆?dòng)起來呢?其實(shí)也很簡單,我們一起來實(shí)現(xiàn)一下

//useLatest
import { useEffect, useRef } from "react"
export default (params:any)=>{
    const latest=useRef();
    useEffect(()=>{
        latest.current=params;
    })
    return latest;
}
//carousel組件 
const Carousel=(props)=>{
    const {
        //initial 為傳入配置 默認(rèn)為0 即默認(rèn)展示第一張圖
        initial=0,
        //是否自動(dòng)輪播 默認(rèn)為是
        autoplay=true,
        //時(shí)間間隔 默認(rèn)為3秒
        interval=3000
    }=props;
    //新建定時(shí)器存儲(chǔ)變量
    const timer:any=useRef(null);
    const [current,setCurrent]=useState<number>(initial);
    const [itemLength]=useState<number>(React.Children.count(children)); 
    //解決閉包問題
    const latest:any=useLatest(current); 
    const autoPlay=()=>{
        //設(shè)置定時(shí)器 每隔3s切換到下一張圖片
        timer.current=setInterval(()=>{
            setStep('next');
        },interval);
    }
    const setStep=(direction:'prev'|'next')=>{
        switch(direction){
            case 'prev':
                let prevStep:number=latest.current-1;
                //當(dāng)為第一張時(shí) 跳到第5張
                if(prevStep===-1){
                    prevStep=itemLength-1;
                }
                setCurrent(prevStep);
                break;
            case 'next':
                let nextStep:number=latest.current+1;
                //當(dāng)為最后一張時(shí) 跳到第1張
                if(nextStep===itemLength){
                    nextStep=0;
                }
                setCurrent(nextStep);
                break;
            default:
        }
    }
    useEffect(()=>{
        if(autoplay){
            //自動(dòng)輪播
            autoPlay();
        }
        return ()=>{
            //銷毀定時(shí)器
            clearInterval(timer.current);
            timer.current=null;
        }
    },[autoplay]);
    return (
        <div className={'carousel'}>
            <div className={'carousel-inner'}> 
                {injecteIndex(children,current)}
            </div> 
        </div>
    )
}  
```# 完成動(dòng)畫
其實(shí)上面我們已經(jīng)把無縫輪播業(yè)務(wù)邏輯完成了,那么如何讓他輪播起來呢?我們這里使用react官方推薦的一個(gè)過渡庫,因?yàn)閞eact并沒有像vue為我們提供transition api。
```js
const CarouselItem=(props)=>{ 
    const {  
        children,
        selfIndex 
    }=props; 
    const visible=selfIndex===current; 
    return  (
        <CSSTransition mountOnEnter unmountOnExit appear in={visible} timeout={500}  classNames={'carousel'}>
            <div className={'carousel-item'} >
                {children}
            </div>
        </CSSTransition>
    ) 
});
.carousel-enter-active,.carousel-exit-active{
        transition: all 500ms linear;
}
.carousel-enter{ 
        transform: translateX(100%);
        opacity: 0.8;
}
.carousel-enter-active{
        transform: translateX(0);
        opacity: 1;
}
.carousel-exit{
        transform: translateX(0); 
        opacity: 1;
}
.carousel-exit-active{
        transform: translateX(-100%); 
        opacity: 0.8;
}

之前我們?cè)O(shè)置的top:0 left:0 可以得出輪播元素的原點(diǎn)都是容器的左上角 在enter過程將translateX從100到0 即可展示從右往左的動(dòng)畫效果 在exit過程前將translateX從0到-100 即可展示從左往右的動(dòng)畫效果

完成小圓點(diǎn)

其實(shí)讓我寫輪播圖的老兄 最大的難點(diǎn)是小圓點(diǎn)的位置 因?yàn)榇蟛糠州啿D 小圓點(diǎn)部分都是寫在inner里面的 而inner元素為overflow:hidden,即不管如何小圓點(diǎn),他都會(huì)溢出隱藏。所以這次我們把小圓點(diǎn)放在inner元素上,并且提供一個(gè)屬性讓小圓點(diǎn)可調(diào)。

//carousel 
<div className={classes}>
    <div className={'inner'}>
        {injecteIndex(children)}
    </div>
    <Dots length={itemLength}  position={dotPosition}/>
</div>
//dots原點(diǎn)
<div className={classnames(
            classes, 
    )} style={{...position}}>
            {
                newArray.map((item,index)=>(
                    <div className={classnames(`${prefixCls}-item`,{
                        'active':current===index
                    })} key={index} onClick={()=>onClick(index)}/>
                ))
            }
</div>

實(shí)現(xiàn)效果

源碼地址

如果大家有想使用的話 可以放心 使用 源碼已發(fā)到github和npm上面

npm install @parrotjs/carousel -S

以上就是react 組件實(shí)現(xiàn)無縫輪播示例詳解的詳細(xì)內(nèi)容,更多關(guān)于react 組件無縫輪播的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解react、redux、react-redux之間的關(guān)系

    詳解react、redux、react-redux之間的關(guān)系

    這篇文章主要介紹了詳解react、redux、react-redux之間的關(guān)系,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • React Native可復(fù)用 UI分離布局組件和狀態(tài)組件技巧

    React Native可復(fù)用 UI分離布局組件和狀態(tài)組件技巧

    這篇文章主要為大家介紹了React Native可復(fù)用 UI分離布局組件和狀態(tài)組件使用技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 關(guān)于React Native使用axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求的方法

    關(guān)于React Native使用axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求的方法

    axios是一個(gè)基于Promise的Http網(wǎng)絡(luò)庫,可運(yùn)行在瀏覽器端和Node.js中,Vue應(yīng)用的網(wǎng)絡(luò)請(qǐng)求基本都是使用它完成的。這篇文章主要介紹了React Native使用axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求,需要的朋友可以參考下
    2021-08-08
  • 一文帶你了解React中的函數(shù)組件

    一文帶你了解React中的函數(shù)組件

    函數(shù)式組件的基本意義就是,組件實(shí)際上是一個(gè)函數(shù),不是類,下面這篇文章主要給大家介紹了關(guān)于React中函數(shù)組件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • 初識(shí)React及React開發(fā)依賴詳解

    初識(shí)React及React開發(fā)依賴詳解

    React由Facebook來更新和維護(hù),它是大量優(yōu)秀程序員的思想結(jié)晶,React的流行不僅僅局限于普通開發(fā)工程師對(duì)它的認(rèn)可,大量流行的其他框架借鑒React的思想,接下來通過本文介紹React基礎(chǔ)及React開發(fā)依賴介紹,需要的朋友可以參考下
    2022-10-10
  • 使用react-native-image-viewer實(shí)現(xiàn)大圖預(yù)覽

    使用react-native-image-viewer實(shí)現(xiàn)大圖預(yù)覽

    這篇文章主要介紹了使用react-native-image-viewer實(shí)現(xiàn)大圖預(yù)覽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 深入研究React中setState源碼

    深入研究React中setState源碼

    這篇文章主要介紹了深入研究React中setState源碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • 淺談React中組件間抽象

    淺談React中組件間抽象

    這篇文章主要介紹了淺談React中組件間抽象,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • React手寫tab切換問題

    React手寫tab切換問題

    今天介紹下React手寫tab切換問題,代碼部分包括父文件,子文件及子文件tab樣式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • react-router browserHistory刷新頁面404問題解決方法

    react-router browserHistory刷新頁面404問題解決方法

    本篇文章主要介紹了react-router browserHistory刷新頁面404問題解決方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-12-12

最新評(píng)論