H5 实现图片可预览缩放等操作(对库 react-photo-view 的封装和使用)

7 篇文章 1 订阅
本文介绍了如何在使用Taro开发的H5应用中,针对Taro预览图片功能的不足,通过封装`PreviewImage`组件,引入`react-photo-view`库来实现图片的放大功能,并提供了详细的代码示例。组件支持显示、关闭、切换图片以及回调事件处理。
摘要由CSDN通过智能技术生成

H5开发,基于 react-photo-view 库,封装实现预览图片、放大缩小图片等功能的业务组件。

一、安装 react-photo-view

yarn add react-photo-view

或者用 npm

npm install react-photo-view

二、封装 PreviewImages 组件

  • 切记引入 import "react-photo-view/dist/react-photo-view.css"; 否则会出现样式异常
import { forwardRef, useCallback, useImperativeHandle, useState } from "react";
import { PhotoProvider, PhotoSlider } from "react-photo-view";
import "react-photo-view/dist/react-photo-view.css";
import type { PhotoProviderProps } from "react-photo-view/dist/PhotoProvider";
import { DataType } from "react-photo-view/dist/types";
import { IPhotoSliderProps } from "react-photo-view/dist/PhotoSlider";

export interface PreviewImagesRef {
  open: ({ index, urls }: { index: number; urls: string[] }) => void;
  close: () => void;
}

type PreviewImagesProps = {
  onClose?: () => void;
  photoProviderProps?: PhotoProviderProps;
} & Omit<IPhotoSliderProps, "visible" | "images" | "onClose">;

const PreviewImages = forwardRef<PreviewImagesRef, PreviewImagesProps>(
  (props, ref) => {
    const { photoProviderProps, ...restPhotoSliderProps } = props;
    const [visible, setVisible] = useState<boolean>(false);
    const [index, setIndex] = useState<number>(0);
    const [images, setImages] = useState<DataType[]>([]);

    const onIndexChange = useCallback(
      (e) => {
        setIndex(e);
        restPhotoSliderProps?.onIndexChange?.(e);
      },
      [restPhotoSliderProps]
    );

    const onClose = useCallback(() => {
      setVisible(false);
      restPhotoSliderProps?.onClose?.();
    }, [restPhotoSliderProps]);

    useImperativeHandle(
      ref,
      () => ({
        open: ({ index: _index, urls }) => {
          const _images = Array.isArray(urls)
            ? urls.map((url, i) => ({ src: url || "", key: i }))
            : [];
          setImages(_images);
          setIndex(_index);
          setVisible(true);
        },
        close: onClose,
      }),
      [onClose]
    );

    return (
      <PhotoProvider {...(props?.photoProviderProps || {})}>
        <PhotoSlider
          photoClosable={false}
          {...(restPhotoSliderProps || {})}
          images={images}
          index={index}
          visible={visible}
          onClose={onClose}
          onIndexChange={onIndexChange}
        />
      </PhotoProvider>
    );
  }
);
export default PreviewImages;

三、使用

1. 示例

import PreviewImages, { PreviewImagesRef } from "@/components/PreviewImages";
import { useRef } from "react";

const pictures = [
  "https://img2.baidu.com/it/u=496754399,526690120&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=904",
  "https://img0.baidu.com/it/u=355339949,1813470147&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=904",
  "https://img2.baidu.com/it/u=1612188668,496483824&fm=253&fmt=auto&app=138&f=JPEG?w=1278&h=800",
  "https://img0.baidu.com/it/u=696957468,70087051&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=599",
];

const TestPreviewImagesComp = () => {
  const previewRef = useRef<PreviewImagesRef>(null);

  return (
    <div>
      <button
        onClick={() => previewRef.current?.open({ urls: pictures, index: 0 })}
      >
        打开图片预览
      </button>
      <PreviewImages ref={previewRef} />
    </div>
  );
};

export default TestPreviewImagesComp;

2. 打开效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值