Swiper10.2.0+Next.js+Mui实现2种轮播图

第一种是点击tab会切换,url改变,同时在切换的时候有轮播图的效果

一开始我想的是用slidesPerview来实现这种一版有多个card,这样就做不了history的跳转,官方给的history demo一个版只有一个slide,如果要做路由history的控制,就得用Mui的Grid来实现。

javascript 复制代码
 <SwiperSlide style={{ height: "100%", width: "100%", marginBottom: "30px" }} data-history="trending" >
                        <Grid
                            container
                            columns={{ xs: 4, sm: 8, md: 12 }}
                            rowSpacing={3} columnSpacing={{ xs: 1, sm: 2, md: 3 }}
                            style={{ height: "100%", marginTop: "20px", width: "100%" }}
                        >
                            {Array.from(Array(16)).map((_, index) => (
                                <Grid xs={2} sm={3} md={3} key={index}>
                                    <Item><MarketCard /></Item>
                                </Grid>
                            ))}
                        </Grid>
                    </SwiperSlide>

这样子就可以有每个Slide都有6个card,之后要做上面的tab切换,注意url栏,是会跟着改变的。这里我一开始是在swiper的history demo(codesandbox.io/s/nshsvn?fi...)里看,发现改了url就会出现对应的slide:

我就想点击tab组件去改url,然后就可以渲染对应的slide,,结果不行,因为项目用的是next.js,如果是用tab组件,确实能够改变url, 但是没有渲染对应的,因为slide它没有对应一个页面,那么该url就没有对应一个路由,就会报错。然后我又想,那就创建一个对应的slide页面吧:

然后在页面里面用类似Layout的组件去包裹:

xml 复制代码
   <TabSwiper>
            <SwiperSlide style={{ height: "100%", marginBottom: "30px" }} data-history="new" >
                <Grid
                    container
                    // spacing={{ xs: 2, md: 13 }}
                    // bgcolor="#FFF"
                    columns={{ xs: 4, sm: 8, md: 12 }}
                    rowSpacing={3} columnSpacing={{ xs: 1, sm: 2, md: 3 }}
                    style={{ height: "100%", marginTop: "20px", width: "100%" }}
                >
                    slide2
                    {Array.from(Array(16)).map((_, index) => (
                        <Grid xs={2} sm={3} md={3} key={index}>
                            <Item><MarketCard /></Item>
                        </Grid>
                    ))}
                </Grid>
            </SwiperSlide>
        </TabSwiper>

这里的TabSwiper就相当于Layout。这样子点击tab是能够切换到对应的slide的了,这里还有个致命的问题:我在切换tab的时候并没有swiper的效果,就是很生硬的跳转,所以我采用另一种方法来实现tab:修改pagination。

pagination本来只是一些圆点和数字,因为点击它可以切换slide,而且路由也跟着改变,所以非常适合改成tab,我们要的tab就是要实现类似的功能:

自定义Pagination:

javascript 复制代码
  const pagination = {
        el: '.swiper-pagination',
        clickable: true,
        modifierClass: "custom-modifier-class",
        horizontalClass: "custom-horizontal-class",
        bulletClass: 'custom-pagination-bullet', // Custom class for pagination bullets
        bulletActiveClass: 'custom-pagination-bullet-active',
        renderBullet: function (index, className) {
​
            return (
                '<span class="' + className + '">' + (tabs[index].label) + '</span>'
            );
        },
    };

这个swiper的全部实现代码:

javascript 复制代码
import React from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Box, } from '@mui/material'
import Grid from '@mui/material/Unstable_Grid2';
import { CSSProperties } from 'react';
​
import 'swiper/css';
import 'swiper/css/grid';
import 'swiper/css/pagination';
​
import { Pagination, History } from 'swiper/modules';
import { experimentalStyled as styled } from '@mui/material/styles';
import Paper from '@mui/material/Paper';
​
import styles from './styles.module.css';
import MarketCard from '../../../components/Market/MarketCard'
import NavTabs from './NavTab';
​
const Item = styled(Paper)(({ theme }) => ({
    backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
    ...theme.typography.body2,
    padding: theme.spacing(2),
    textAlign: 'center',
    color: theme.palette.text.secondary,
}));
​
const tabs = [
    { label: 'Trending', href: '/Home/TabSwiper/slides/trending' },
    { label: 'New', href: '/Home/TabSwiper/slides/new' },
    { label: 'Ending Soon', href: '/slides/ending' },
    { label: 'Volume', href: '/slides/volume' },
    { label: 'Liquidity', href: '/slides/liquidity' },
];
​
export default function TabSwiper() {
    const pagination = {
        el: '.swiper-pagination',
        clickable: true,
        modifierClass: "custom-modifier-class",
        horizontalClass: "custom-horizontal-class",
        bulletClass: 'custom-pagination-bullet', // Custom class for pagination bullets
        bulletActiveClass: 'custom-pagination-bullet-active',
        renderBullet: function (index, className) {
​
            return (
                '<span class="' + className + '">' + (tabs[index].label) + '</span>'
            );
        },
    };
    return (
        <>
            <div className="swiper-pagination"></div>
​
            <Box sx={{ position: "relative", height: "68rem", width: "100%", }}>
                <Swiper
                    slidesPerView={1}
                    grid={{
                        fill: "row",
                        rows: 1,
                    }}
                    spaceBetween={30}
                    history={{
                        key: '/home/tabswiper/slides',
                    }}
​
                    pagination={pagination}
​
                    modules={[Pagination, History]}
                    className={styles.swiper}
                >
                    <SwiperSlide style={{ height: "100%", width: "100%", marginBottom: "30px" }} data-history="trending" >
                        <Grid
                            container
                            columns={{ xs: 4, sm: 8, md: 12 }}
                            rowSpacing={3} columnSpacing={{ xs: 1, sm: 2, md: 3 }}
                            style={{ height: "100%", marginTop: "20px", width: "100%" }}
                        >
                            {Array.from(Array(16)).map((_, index) => (
                                <Grid xs={2} sm={3} md={3} key={index}>
                                    <Item><MarketCard /></Item>
                                </Grid>
                            ))}
                        </Grid>
                    </SwiperSlide>
                    <SwiperSlide style={{ height: "100%", marginBottom: "30px" }} data-history="new" >
                        <Grid
                            container
                            columns={{ xs: 4, sm: 8, md: 12 }}
                            rowSpacing={3} columnSpacing={{ xs: 1, sm: 2, md: 3 }}
                            style={{ height: "100%", marginTop: "20px", width: "100%" }}
                        >
                            slide2
                            {Array.from(Array(16)).map((_, index) => (
                                <Grid xs={2} sm={3} md={3} key={index}>
                                    <Item><MarketCard /></Item>
                                </Grid>
                            ))}
                        </Grid>
                    </SwiperSlide>
                    <SwiperSlide style={{ height: "100%", marginBottom: "30px" }} data-history="ending" >Custom Slide 3</SwiperSlide>
                    <SwiperSlide style={{ height: "100%", marginBottom: "30px" }} data-history="volume" >Custom Slide 4</SwiperSlide>
                    <SwiperSlide style={{ height: "100%", marginBottom: "30px" }} data-history="liquidity" >Custom Slide 5</SwiperSlide>
                </Swiper>
            </Box>
        </>
    );
}
​
​

第二种Swiper:

除了这个效果,UI还要实现悬浮在某个card,某个card就扩大的效果。

这个就用到了SlidePerview。此外还有一点和原本swiper提供的组件不太一样的就是它的左右按钮,需要我们自己加上去。

详细代码:

悬浮在card后,card就会变大:在原有 SwiperSlide的基础上自定义一个slide

less 复制代码
const StyledSwiperSlide = styled(SwiperSlide)(({ theme }) => ({
    // Your slide styles here
    position: "relative", /* Ensure positioning context */
    transition: "transform 0.3s ease",
    // Add hover effect
    '& :hover': {
        transform: 'scale(1.03)', // Scale up the slide by 5% on hover
        zIndex: 2, // Optional: Adjust z-index for layering
        boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.3)', // Optional: Add a shadow
    },
}));

增加左右按钮:以右边(上一页)的按钮为例

arduino 复制代码
  <Box
                className='custom-prev-button'
                sx={{
                    justifyContent: "center",
                    alignItems: "center",
                    position: "absolute",
                    top: "calc(50% - 20px)",
                    borderRadius: "10px",
                    boxShadow: "var(--shadows-dropShadowSm)",
                    zIndex: 999,
                    transition: " all 0.2s ease 0s",
                    cursor: "pointer",
                    display: "flex",
​
                    left: "-16px",
                    opacity: 1
                }}
            >
                <Image src={pre} alt="" width="40" height="40" />
            </Box>

然后将这两个按钮放在Swiper外面就可以:

最终效果:

相关推荐
符文师29 分钟前
css3 新特性
前端·css3
ct9781 小时前
WebGL开发
前端·gis·webgl
C_心欲无痕1 小时前
前端页面渲染方式:CSR、SSR、SSG
前端
果粒蹬i1 小时前
生成式 AI 质量控制:幻觉抑制与 RLHF 对齐技术详解
前端·人工智能·easyui
WordPress学习笔记2 小时前
解决Bootstrap下拉菜单一级链接无法点击的问题
前端·bootstrap·html
Never_Satisfied2 小时前
C#插值字符串中大括号表示方法
前端·c#
踢球的打工仔3 小时前
typescript-类
前端·javascript·typescript
天天打码3 小时前
Svelte-无虚拟DOM、极致性能的现代高性能Web开发框架!
前端·node.js·vue·svelte
0思必得03 小时前
[Web自动化] Selenium元素定位
前端·python·selenium·自动化·html
EEEzhenliang4 小时前
CSS知识概括、总结
前端·css