最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

正文

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

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

無(wú)縫輪播

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

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

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

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

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

參考了大部分輪播圖組件,得出來(lái)下面的這種使用結(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 來(lái)充當(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)前輪播圖元素

之前我們說(shuō)過(guò)這次我們輪播圖的核心思路是顯示當(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)起來(lái)呢?其實(shí)也很簡(jiǎn)單,我們一起來(lái)實(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)); 
    //解決閉包問(wèn)題
    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)畫(huà)
其實(shí)上面我們已經(jīng)把無(wú)縫輪播業(yè)務(wù)邏輯完成了,那么如何讓他輪播起來(lái)呢?我們這里使用react官方推薦的一個(gè)過(guò)渡庫(kù),因?yàn)閞eact并沒(méi)有像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過(guò)程將translateX從100到0 即可展示從右往左的動(dòng)畫(huà)效果 在exit過(guò)程前將translateX從0到-100 即可展示從左往右的動(dòng)畫(huà)效果

完成小圓點(diǎn)

其實(shí)讓我寫(xiě)輪播圖的老兄 最大的難點(diǎn)是小圓點(diǎn)的位置 因?yàn)榇蟛糠州啿D 小圓點(diǎn)部分都是寫(xiě)在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)無(wú)縫輪播示例詳解的詳細(xì)內(nèi)容,更多關(guān)于react 組件無(wú)縫輪播的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • useEvent顯著降低Hooks負(fù)擔(dān)的原生Hook

    useEvent顯著降低Hooks負(fù)擔(dān)的原生Hook

    這篇文章主要為大家介紹了useEvent顯著降低Hooks負(fù)擔(dān)的原生Hook示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • TypeScript在React中的應(yīng)用技術(shù)實(shí)例解析

    TypeScript在React中的應(yīng)用技術(shù)實(shí)例解析

    這篇文章主要為大家介紹了TypeScript在React中的應(yīng)用技術(shù)實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 詳解React之父子組件傳遞和其它一些要點(diǎn)

    詳解React之父子組件傳遞和其它一些要點(diǎn)

    這篇文章主要介紹了詳解React之父子組件傳遞和其它一些要點(diǎn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • React安裝node-sass失敗解決方案分享

    React安裝node-sass失敗解決方案分享

    Node-sass是一個(gè)庫(kù),它將Node.js綁定到LibSass(流行樣式表預(yù)處理器Sass的C版本),它允許用戶以令人難以置信的速度將.scss文件本地編譯為css,并通過(guò)連接中間件自動(dòng)編譯,下面這篇文章主要給大家介紹了關(guān)于React安裝node-sass失敗解決的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • 一文搞懂?React?18?中的?useTransition()?與?useDeferredValue()

    一文搞懂?React?18?中的?useTransition()?與?useDeferredValue()

    這篇文章主要介紹了一文搞懂?React?18?中的?useTransition()與useDeferredValue(),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • React進(jìn)行路由變化監(jiān)聽(tīng)的解決方案

    React進(jìn)行路由變化監(jiān)聽(tīng)的解決方案

    在現(xiàn)代單頁(yè)應(yīng)用(SPA)中,路由管理是至關(guān)重要的一部分,它不僅決定了用戶如何在頁(yè)面間切換,還直接影響到整個(gè)應(yīng)用的性能和用戶體驗(yàn),這些看似不起眼的問(wèn)題,往往會(huì)導(dǎo)致功能錯(cuò)亂和性能下降,本篇文章將深入探討在 React 中如何高效監(jiān)聽(tīng)路由變化,需要的朋友可以參考下
    2025-01-01
  • 解讀useState第二個(gè)參數(shù)的"第二個(gè)參數(shù)"

    解讀useState第二個(gè)參數(shù)的"第二個(gè)參數(shù)"

    這篇文章主要介紹了useState第二個(gè)參數(shù)的"第二個(gè)參數(shù)",具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React根據(jù)寬度自適應(yīng)高度的示例代碼

    React根據(jù)寬度自適應(yīng)高度的示例代碼

    本篇文章主要介紹了React根據(jù)寬度自適應(yīng)高度的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • react如何實(shí)現(xiàn)篩選條件組件

    react如何實(shí)現(xiàn)篩選條件組件

    這篇文章主要介紹了react如何實(shí)現(xiàn)篩選條件組件問(wèn)題,具有很好的參考價(jià)價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼

    React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼

    這篇文章主要介紹了React+EggJs實(shí)現(xiàn)斷點(diǎn)續(xù)傳的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

密山市| 中西区| 辉县市| 济南市| 同德县| 明光市| 江孜县| 柏乡县| 洪泽县| 岳西县| 夏邑县| 方正县| 石柱| 淮阳县| 沾化县| 孟津县| 石屏县| 龙里县| 尼木县| 高陵县| 潜山县| 旬阳县| 灌南县| 扶风县| 嵊泗县| 晋宁县| 淮北市| 汽车| 甘谷县| 镇巴县| 桐城市| 射洪县| 临泉县| 尼玛县| 大庆市| 桃源县| 临海市| 衡南县| 汾阳市| 黑河市| 广饶县|