
import { Button, Upload, Modal, Alert } from 'antd'
import React, { Children, cloneElement, isValidElement, useState, useEffect, useRef } from 'react'
import axios from 'axios'
const Previewer = ({ url, onClose, isEditing, onEditSave }) =>{
return (
<Modal className={styles.modalshow} title={isEditing ? "文档编辑" : "文档预览"} visible width={1200} onCancel={onClose} footer={
isEditing ? [
<Button key="back" onClick={onClose}>
返回
</Button>,
<Button key="submit" type="primary" onClick={onEditSave}>
提交
</Button >
] : null} >
<iframe src={url} title='wps' width='100%' height='592' />
</Modal >
)
}
const mapDOMTree = (children, matchChild) =>{
if (typeof children === 'function') return null
return Children.map(children, (child) =>{
if (!child) return null
if (matchChild(child)) return matchChild(child)
return isValidElement(child) ? cloneElement(child, child.props, mapDOMTree(child.props.children, matchChild)) : child
})
}
const baseUrl2 = getUrl('/contract/api/xft-contract-procode/object/v1/attachments/service/create-uri-by-id')
function CUpload({ onPreview, onEdit, onEditSave, children, showDownloadIcon = true, showRemoveIcon = true, showEditButton = true, showPreviewIcon = true, ...rest }) {
const [visible, setVisible] = useState(false)
const [url, setUrl] = useState()
const [editing, setEditing] = useState(false)
const toggle = () =>{
setVisible(prevVisible =>!prevVisible)
}
const onPreviewFile = async (file) =>{
const previerUrl = await onPreview?.(file)
setUrl(previerUrl)
toggle()
}
const onEditFile = async (file) =>{
const previerUrl = await onEdit?.(file)
setUrl(previerUrl)
setEditing(true)
toggle()
}
const handleUpload = files =>{
return {
fileName: files.name,
fileType: files.type
}
}
const onClose = () =>{
setEditing(false)
toggle()
}
const downloadd = (file) =>{
axios.post(`${baseUrl2}?id=${file.id} `)
.then(res =>{
let data = res.data.data
download(data.tempUri, data.fileName)
}
).catch((error) =>{
Modal.showServeError(error)
})
}
const download = (url, fileName) =>{
// for IE
// if (window.navigator.msSaveOrOpenBlob) {
// window.navigator.msSaveOrOpenBlob(url, fileName)
// } else {
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.download = fileName
// document.body.appendChild(link)
link.click()
// window.URL.revokeObjectURL(link.href)
link.remove()
// }
}
const editClose = async () =>{
await onEditSave()
onClose()
}
const baseUrl = getUrl('contract/api/xft-contract-procode/object/v1/attachments')
return (
<>
<Upload
{...rest}
maxCount={1}
data={handleUpload}
accept='application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/msword'
action={baseUrl}
showUploadList={{
showDownloadIcon,
showRemoveIcon,
}}
onDownload={downloadd}
itemRender={(originNode, file) =>{
if (originNode.type !== 'div' || !showPreviewIcon) return originNode
return mapDOMTree(originNode, (children) =>{
if (children.key === 'download-delete') {
return cloneElement(
children,
children.props,
<>
<Button
type="text"
size="small"
onClick={() =>onPreviewFile(file)}
className="ant-upload-list-item-card-actions-btn"
icon={<EyeOutlined />}
title="Preview File"
/>
{showEditButton &&<Button
type="text"
size="small"
onClick={() =>onEditFile(file)}
className="ant-upload-list-item-card-actions-btn"
icon={<EditOutlined />}
title="Edit File"
/>}
{children.props.children}
</>,
)
}
return false
})
}}
>{children}</Upload>
{visible &&<Previewer url={url} onClose={onClose} isEditing={editing} onEditSave={editClose} />}
</>
)
}
export default function UploadButton(props) {
const { setValue, id, mingzi, formItemValue, setPrinstineValue, isEdit } = props
const [list, setList] = useState([])
const editingRef = useRef(false)
console.log('props--', props)
useEffect(() =>{
if (formItemValue?.fileId) {
setList([{ ...formItemValue, name: formItemValue?.fileName, id: formItemValue?.fileId, status: 'done' }])
}
}, [formItemValue])
const onChange = (info) =>{
console.log('info---', info)
if (info.file.status === 'done') {
setValue({ [id]: info.file.response.data.data, [mingzi]: info.fileList[0].name })
}
if (info.file.status === 'removed') {
setPrinstineValue(undefined)
setValue(undefined)
}
setList(info.fileList)
}
const onPreview = (e) =>{
editingRef.current = false
return Http.get('/contract/api/xft-contract-procode/common/v1/preview?attachId=' + e.fileId).then(res =>res.data.data.data).catch((error) =>{
Modal.showServeError(error)
})
}
const onEdit = (e) =>{
editingRef.current = true
return Http.get(`/contract/api/xft-contract-procode/contract/v1/institution/file/onlineEdit?attachId=${props.formItemValue?.fileId}&id=${props.data.__super.id}`).then(
res =>res.data.data.data).catch((error) =>{
Modal.showServeError(error)
})
}
const onEditSave = () =>{
if (editingRef.current) {
editingRef.current = false
return Http.get(`/contract/api/xft-contract-procode/common/v1/complete/fileEdit/${props.formItemValue?.fileId}`)
}
}
const uploadButton = <Button>上传</Button>
return (
<CUpload
onPreview={onPreview}
onEdit={onEdit}
onEditSave={onEditSave}
onChange={onChange}
fileList={list}
showRemoveIcon={isEdit}
showEditButton={isEdit}
>
{list.length >= 1 ? null : uploadButton}
</CUpload>
)
}
很多组件库自身就支持定制主题,这种情况适合于有明确组件设计规范的项目使用。下面是一些定制主题的文档:
当 React 项目使用了 css-modules ,可以在 component 级别覆盖组件库的样式。比如使用了 antd 的组件,但是组件的样式与设计稿的样式有些许出入,既可以通过 CSS modules 的 global 来进行样式覆盖。
如果样式覆盖顺序没有生效,可以加上 !important
一般组件都会留有 API 来自定义一些东西。比如容器样式、关闭按钮、内部组件样式、图标替换等。如果这个组件被应用到一个地方,直接在组件 API 上定义改动即可。如果这个组件会被反复使用。就可以进行组件的二次封装。
下面我基于 antd 的 Modal 组件的二次封装,整个项目都改用封装后的 Modal 组件。
之前遇到一个需要需要将表格多选功能改为 鼠标 hover 的时候显示 checkbox 而非 hover 情况下显示为数字序号 。这个需求在我们用到的 ali-react-table 中并没有相关 API 实现。
既然无法实现需求,就放弃用这个库吗?非也!可以通过将项目 fork 下来,修改源码来实现。且如果这个库有后续的更新,也可以将主仓库的改动合并到 fork 的仓库中。
而在 package.json 的引用中,改为引用 fork 下来的项目即可。这里的引用可以直接引用 git 路径,也可以发到 npm 上去引用。
或许还有别的重写组件的方法,但目前来看以上四种方法都是比较优雅的。
一、去除Antd的Button组件两个汉字中间的空格
二、去掉input聚焦时的蓝色边框
三、去掉点击button时的动画
四、替换搜索框的icon
五、修改树形控件选中项的背景色
六、解决react里input输入时显示[object Object]
七、ant design的气泡卡片组件Popover的d窗里设置输入框
从content属性入手,content属性值设置为包含input的组件(该组件里不要使用Input组件,直接使用input,否则崩溃)
八、设置input的宽度随输入内容长度的变化而变化:
设置一个兄弟节点span,span显示的内容绑定input的value,通过定位让span隐藏在input下
九、如何让antd的Modal组件的确认和取消不显示
十、如何改变Icon的大小和颜色
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)