Taro 微信小程序轮播图 Swiper 组件缩放效果实现

本文介绍了如何使用Vant库中的Swiper组件创建一个轮播图,并自定义item之间的间距。开发者展示了如何设置previousMargin和nextMargin以适应屏幕尺寸,并处理图片点击事件。

效果预览

请添加图片描述

预备知识

前边距&后边距

image.png

SwiperItem

  1. SwiperItem 之间是没有间隔的,它们是连接在一起的。
  2. SwiperItem 的宽度无法更改,只能默认 100%。

计算 previousMargin & nextMargin

数值单位都是 rpx

标题
原始图片宽度600屏幕总宽度750
原始图片两侧剩余宽度750 - 600 = 150单侧剩余宽度150 / 2 = 75
previousMargin & nextMargin75

image.png

完整代码

const banners = [
  {
    src: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg',
    text: '轮播图标题 1'
  },
  {
    src: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg',
    text: '轮播图标题 2'
  },
  {
    src: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-3.jpeg',
    text: '轮播图标题 3'
  },
  { src: 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-4.jpeg', text: '轮播图标题 4' }
];

export const CustomSwiper = () => {
  const [currentIdx, setCurrentIdx] = useState(0);
  const handleSwiperChange = e => {
    setCurrentIdx(e.detail.current);
  };

  return (
    <Swiper
      className="swiper"
      autoplay
      circular
      previousMargin="75rpx"
      nextMargin="75rpx"
      onChange={handleSwiperChange}
    >
      {banners.map((banner, index) => {
        return (
          <SwiperItem key={banner.src}>
            <View className={clsx('swiper__wrap', { active: currentIdx === index })}>
              <Image
                className="swiper__img"
                src={banner.src}
                onTap={() => {
                  console.log(`点击了第${index}张轮播图`);
                }}
              />
              <View className="swiper__text">{banner.text}</View>
            </View>
          </SwiperItem>
        );
      })}
    </Swiper>
  );
};
.swiper {
  width: 100%;
  height: 338px;
  position: relative;

  &__wrap {
    width: auto;
    height: inherit;
    border-radius: 20px;
    transform: scale(0.9);
    transition: all 0.5s ease;

    &.active {
      transform: scale(1);
    }
  }

  &__img {
    width: 600px;
    height: inherit;
    border-radius: 20px;
  }

  &__text {
    position: absolute;
    bottom: 0;
    padding-left: 20px;
    box-sizing: border-box;
    width: 100%;
    height: 78px;
    line-height: 78px;
    font-weight: 500;
    font-size: 32px;
    color: #fff;
    border-radius: 0px 0px 20px 20px;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.9) 100%);
  }
}
### 如何在 Taro 框架中实现组件调用子组件的方法 在 Taro 中,可以通过 `ref` 来访问子组件实例并调用其方法。这种方式类似于 React 的操作逻辑,允许父组件直接与子组件交互。以下是具体实现方式: #### 使用 Ref 访问子组件实例 Taro 提供了 `useRef` 或 `createRef`(针对类组件)来创建一个引用对象,该对象可以绑定到子组件实例上。一旦绑定了子组件实例,父组件便能够通过这个引用调用子组件中的公开方法。 ```jsx // 子组件 (ChildComponent.js) import Taro from '@tarojs/taro'; import { View } from '@tarojs/components'; export default class ChildComponent extends Taro.Component { fetchData() { console.log('正在从子组件获取数据...'); // 假设这里是实际的数据请求逻辑 } render() { return ( <View>这是子组件</View> ); } } ``` ```jsx // 父组件 (ParentComponent.js) import Taro from '@tarojs/taro'; import { View } from '@tarojs/components'; import ChildComponent from './ChildComponent'; export default class ParentComponent extends Taro.Component { constructor(props) { super(props); this.childRef = Taro.createRef(); // 创建 ref 对象 } handleCallChildMethod = () => { const childInstance = this.childRef.current; if (childInstance && typeof childInstance.fetchData === 'function') { childInstance.fetchData(); } }; render() { return ( <View> {/* 绑定 ref 到子组件 */} <ChildComponent ref={this.childRef} /> <Button onClick={this.handleCallChildMethod}>调用子组件方法</Button> </View> ); } } ``` 上述代码展示了如何利用 `ref` 在父组件中调用子组件的 `fetchData` 方法[^1]。 --- #### 函数式组件的支持 如果使用的是函数式组件,则需要借助 `forwardRef` 和 `useImperativeHandle` API 来暴露子组件的功能给父组件。 ```jsx // 子组件 (FunctionalChildComponent.js) import Taro, { forwardRef, useImperativeHandle } from '@tarojs/taro'; import { View } from '@tarojs/components'; const FunctionalChildComponent = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ fetchData: () => { console.log('来自函数式子组件的 fetch 数据'); }, })); return <View>这是一个函数式子组件</View>; }); export default FunctionalChildComponent; ``` ```jsx // 父组件 (ParentComponentWithFunctionChild.js) import Taro from '@tarojs/taro'; import { Button, View } from '@tarojs/components'; import FunctionalChildComponent from './FunctionalChildComponent'; export default function ParentComponentWithFunctionChild() { const functionalChildRef = Taro.useRef(); const callFunctionalChildMethod = () => { const instance = functionalChildRef.current; if (instance && typeof instance.fetchData === 'function') { instance.fetchData(); } }; return ( <View> <FunctionalChildComponent ref={functionalChildRef} /> <Button onClick={callFunctionalChildMethod}>调用函数式子组件方法</Button> </View> ); } ``` 此部分实现了基于函数式组件的方式让父组件调用子组件方法[^4]。 --- #### 关于 Taro 特殊场景下的注意事项 由于 Taro 是一种跨端框架,在某些情况下可能会因为编译器优化而导致额外的行为差异。例如,React 类型的组件被转化为小程序自定义组件时,可能需要两次初始化过程以完成渲染和状态同步。因此建议开发者始终测试最终的小程序表现是否符合预期。 --- ### 总结 无论是类组件还是函数式组件,都可以通过 `ref` 实现组件对子组件方法的调用。对于复杂业务需求,推荐合理设计父子组件之间的职责划分,并注意性能影响以及潜在兼容性问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值