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

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

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

正文

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

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

無縫輪播

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

實現(xiàn)思路

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

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

構(gòu)思使用時代碼結(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組件,這個組件是組件的整體框架文件。

內(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組件,這個組件是Carousel組件的子組件,是輪播圖列表每一項的容器。

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

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

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

完善組件

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

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

carousel組件內(nèi)有一個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>}
    )
}
  • 實現(xiàn)autoPlay

上面我們其實已經(jīng)實現(xiàn)了第一張圖的展示,那么我們?nèi)绾巫屗麆悠饋砟兀科鋵嵰埠芎唵?,我們一起來實現(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,
        //是否自動輪播 默認(rèn)為是
        autoplay=true,
        //時間間隔 默認(rèn)為3秒
        interval=3000
    }=props;
    //新建定時器存儲變量
    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è)置定時器 每隔3s切換到下一張圖片
        timer.current=setInterval(()=>{
            setStep('next');
        },interval);
    }
    const setStep=(direction:'prev'|'next')=>{
        switch(direction){
            case 'prev':
                let prevStep:number=latest.current-1;
                //當(dāng)為第一張時 跳到第5張
                if(prevStep===-1){
                    prevStep=itemLength-1;
                }
                setCurrent(prevStep);
                break;
            case 'next':
                let nextStep:number=latest.current+1;
                //當(dāng)為最后一張時 跳到第1張
                if(nextStep===itemLength){
                    nextStep=0;
                }
                setCurrent(nextStep);
                break;
            default:
        }
    }
    useEffect(()=>{
        if(autoplay){
            //自動輪播
            autoPlay();
        }
        return ()=>{
            //銷毀定時器
            clearInterval(timer.current);
            timer.current=null;
        }
    },[autoplay]);
    return (
        <div className={'carousel'}>
            <div className={'carousel-inner'}> 
                {injecteIndex(children,current)}
            </div> 
        </div>
    )
}  
```# 完成動畫
其實上面我們已經(jīng)把無縫輪播業(yè)務(wù)邏輯完成了,那么如何讓他輪播起來呢?我們這里使用react官方推薦的一個過渡庫,因為react并沒有像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;
}

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

完成小圓點

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

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

實現(xiàn)效果

源碼地址

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

npm install @parrotjs/carousel -S

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

相關(guān)文章

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

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

    這篇文章主要介紹了詳解react、redux、react-redux之間的關(guān)系,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    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ò)請求的方法

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

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

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

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

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

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

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

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

    深入研究React中setState源碼

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

    淺談React中組件間抽象

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

    React手寫tab切換問題

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

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

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

最新評論