最近一个需求是图片要实现预览并且可以上下切换,react接触不是很久,查了好多资料,最终对@hanyk/rc-viewer下手,jquery用多了伙伴都知道viewer.js,一个很强大的图片预览插件。
rc-viewer就是viewer.js的react版,我分享一下自己使用rc-viewer遇到的问题,希望对要用这个组件的小伙伴有帮助。
一、安装@hanyk/rc-viewer,安装命令如下:
npm install @hanyk/rc-viewer
二、引入
import RcViewer from '@hanyk/rc-viewer';
具体代码如下:
import React, { useState, useEffect } from 'react';
import { UploadOutlined } from '@ant-design/icons';
import { Upload, message, Button, Popover } from 'antd';
import RcViewer from '@hanyk/rc-viewer';
export default function Input(p) {
const [fileArr, setFileList] = useState([]); // 附件
const [previewImgUrl, setPreviewImgUrl] = useState([]); // 拼接图片路径
const [preview, setPreview] = useState(null); //预览
useEffect(() => {
let imgUrl = [];
let list =[
{
"sFileName": "d009b3de9c82d158d5fdc0c2cf768ddebd3e42cc.jpeg",
"sFilePath": "group1/M00/09/2E/Cu5rImIceUSAbjK7AAB6wZb2_fI76.jpeg",
"id": 1,
},
{
"sFileName": "eaafae4424e7596718256329f395e6fe.jpeg",
"sFilePath": "group1/M00/09/2E/Cu5rImIceVWAOxJaAAAqjqO_OA470.jpeg",
"id": 2,
},
{
"sFileName": "gonggao.png",
"sFilePath": "group1/M00/09/2E/Cu5rImIceV6ANatPAABNizbaqCc515.png",
"id": 3,
}
]
setFileList([...list]);
for(var i=0;i < list.length;i++){
let dd = `http://127.0.0.1:8888/` + list[i].sFilePath;
imgUrl.push(dd)
}
setPreviewImgUrl([...imgUrl])
}, []);
// 图片预览
const options = {
// 是否显示下面工具栏 1 显示 0 隐藏
// toolbar: 1,
navbar: false, //关闭缩略图
fullscreen: false, //播放全屏
loop: false, //是否循环 上一个 下一个
minWidth:'',
minHeight:'',
toolbar: {
zoomIn: { size: 'large' }, //放大
zoomOut: { size: 'large' }, //缩小
reset: { size: 'large' }, //重置
prev: { show: true, size: 'large', }, //上一张
play: { show: false, size: 'large', }, //播放
next: { show: true, size: 'large', }, //下一张
rotateLeft: { size: 'large' }, //左旋转
rotateRight: { size: 'large' }, //右旋转
flipHorizontal: { size: 'large' }, //左右翻转
flipVertical: { size: 'large' }, //上下翻转
},
// 关闭时的回调
hide() {
setPreviewImgUrl([]);
let imgUrl = [];
for(var i=0;i < fileArr.length;i++){
let dd = `http://127.0.0.1:8888/` + fileArr[i].sFilePath;
imgUrl.push(dd);
}
//赋值给previewImgUrl
setPreviewImgUrl([...imgUrl]);
},
};
const previewImg = (fileObj) => {
let imgUrls = [];
let url = `http://10.238.107.43:8888/` + fileObj.sFilePath;
imgUrls.push(url);
for(var i=0;i < fileArr.length;i++){
let dd = `http://127.0.0.1:8888/` + fileArr[i].sFilePath;
if(imgUrls.indexOf(dd) === -1){
imgUrls.push(dd)
}
}
//赋值给previewImgUrl
setPreviewImgUrl([...imgUrls]);
if (preview) {
preview.viewer.show();
}
}
return (
<div>
{fileArr &&
fileArr.length > 0 &&(
<>
<div style={{ display: "none" }}>
<RcViewer
options={options}
ref={(v) => {
setPreview(v);
}}
>
<ul id="images">
<li>
{previewImgUrl.map((item,index) => {
return (
<div key={index}>
<img src={item} alt="" />
</div>
)}
)}
</li>
</ul>
</RcViewer>
</div>
{fileArr.map((item, index) => {
return (
<div key={index} className="ant-file-content">
<img src={getFileType(item.sFileName)} className="ant-image" />
<a
key={index}
href="javascript:void(0)"
rel="noopener noreferrer"
className="ant-text"
onClick={() => previewImg(item)}
>
{item.sFileName}
</a>
<Popover content="预览" title="" trigger="hover">
<img
src={previewIcon}
className="ant-image"
onClick={() => previewImg(item)}
></img>
</Popover>
</div>
);
}
)}
</>
)}
</div>
);
}
因为后端传过来的数据不止包含图片路径,所以我把传过来的数据拿到路径重新拼了个只有路径的数组,再进行预览。
在这个过程中有两个坑给大家分享一下:
1.刚开始我的图片路径拼接是在点击预览事件的时候处理的,但是发现第一次点击预览,函数走了,预览失败,需要点击第二次才可以,最后将图片路径拼接在组件初始化的时候也处理了一下,次问题解决;
2.因为我这边图片预览的list和附件展示的list是分开的,导致上下切换的时候,顺序混乱,点击预览的并非自己所点的图片,一直以为是自己处理图片数组有问题,后面发现是在关闭预览的时候没有把图片数组置空,于是就在关闭的时候置空了一下图片数组,该问题解决了。
3.在关闭预览的时候,我又处理了一下图片路径数组,避免在关闭置空数据后再打开需要点两次;
关于@hanyk/rc-viewer,我目前没有找到中文的文档,英文文档如下:
里面有options的配置,但是我个人感觉可以参考一下viewer.js里的options配置,下面分享的这个博客里options配置说的比较全,可以参考一下。
Viewer.js的使用_神奇的酱油的博客-优快云博客_viewer.js
我实现的效果:
希望对小伙伴有帮助,有不正确的地方也欢迎指出。