【图片预览】第三种方式:将组件数据放在公共状态下
背景:考虑到项目中很多页面都需要图片查看器,每个页面都去引入ImgViewer组件有点麻烦,现在将ImgViewer组件放在公共状态下
1、models/imgViewer.ts
import { Reducer } from 'umi' export interface ImgViewerModelState { visible?: boolean // 显示隐藏,默认:false images: Array<object> // 图片列表,必传,格式:[{ alt: '', src: '', downloadUrl: '' }] activeIndex?: number // 当前展示图片的下标,默认:0 downloadable?: boolean // 是否支持下载,默认:true } interface ImgViewerType { namespace: 'imgViewer' state: ImgViewerModelState reducers: { setState: Reducer<ImgViewerModelState> } } const ImgViewerModel: ImgViewerType = { namespace: 'imgViewer', state: { visible: false, images: [], activeIndex: 0, downloadable: true }, reducers: { /* 调用setState时, 如果visible为false,其他参数不用传,用默认的值 如果visible为true,images必传,visible和downloadable为true,可不传,activeIndex一般需要传 */ setState(state, { visible = true, images = [], activeIndex = 0, downloadable = true }): ImgViewerModelState { return { visible, images, activeIndex, downloadable } } } } export default ImgViewerModel
2、models/connect.d.ts
引入imgViewer模块
import type { ImgViewerModelState } from './imgViewer'
暴露出去
export interface ConnectState {
imgViewer: ImgViewerModelState
}
3、ImgViewer/index.tsx
import React from 'react' import Viewer from 'react-viewer' import { connect } from 'umi' import './index.less' const ImgViewer: React.FC = (props: any) => { const { visible, images, activeIndex = 0, downloadable = true, dispatch } = props const handleClose = () => dispatch({ type: 'imgViewer/setState', visible: false }) return ( <Viewer visible={visible} images={images} activeIndex={activeIndex} onClose={handleClose} onMaskClick={handleClose} // 点击遮罩关闭 downloadable={downloadable} // 是否显示下载按钮,默认显示,显示时imgs对象中需要有downloadUrl字段 downloadInNewWindow // 新窗口打开图片 /> ) } export default connect()(ImgViewer)
index.less
.react-viewer { position: absolute; z-index: 10000; }
4、BasicLayout.tsx关键代码
import { ImgViewerModelState } from 'umi' // 引入umi中的ImgViewerModelState接口 import { ConnectState } from '@/models/connect' // 引入ConnectState将当前组件编程高阶组件 import ImgViewer from '@/components/ImgViewer' // 引入组件 // 接口中指明imgViewer的指向,否则从props中解构会报红 interface BasicLayoutProps { imgViewer: ImgViewerModelState } const BasicLayout: React.FC<BasicLayoutProps> = (props) => { const { imgViewer: { visible, images, activeIndex, downloadable } } = props // 图片查看器的状态 return ( <ProLayout> <ImgViewer visible={visible as boolean} images={images as Array<object>} activeIndex={activeIndex} downloadable={downloadable} /> </ProLayout> ) } // 添加imgViewer export default connect(({ global, settings, night, imgViewer }: ConnectState) => ({ collapsed: global.collapsed, settings, night, imgViewer }))(BasicLayout)
5、使用
import { connect, Dispatch } from 'umi' // 引入connect和Dispatch // 接口中定义dispatch interface PropsType { dispatch: Dispatch } // 图片预览的回调中通过dispatch去修改公共状态 const handleImgPreview = (list: Array<any>, activeIndex: number) => { const { dispatch } = props const images: Array<object> = list.map(({ alt, src }) => ({ alt, src, downloadUrl: src })) dispatch({ type: 'imgViewer/setVisible', images, activeIndex }) } export default connect()(Content) // 导出时改为高阶组件