当前位置:首页 » 文件管理 » react上传文件

react上传文件

发布时间: 2024-08-28 14:56:20

① 如何制作react组件包上传到npm

虽说现在市面上组件库相当多了,但是还有一些组件特定场景市面上没有,公司内部一些不同项目,有类似相同组件可以直接复用,避免重复造轮子,就可以直接制作一个npm包,下次直接使用。

注意:文中的每一步都很重要,都是踩过的坑

1、注册npm账号
地址: https://www.npmjs.com/signup
注意:注册完后,记得验证你的邮件地址!一定!否则会在提交组件包的时候报403错误,那是因为没有验证你的邮箱。

1、创建新的文件夹
2、进入该文件夹,使用cmd命令,npm进入安装项目流程

3、对应的字段:

有需要可以自行安装自己要的依赖,上面几个是我写组件必要的几个依赖,因为我没有写对应的依赖版本所以安装时候会以最新版本安装。

1、新建如下目录结构和文件

2、编写webpack.config.js的配置,以下是最基础的配置

上面的less-loader没有启用lessmoles模块化比较不好,假设现在项目有好几个组件,那么模块化就可以避免我们不同组件的样式污染,如果不开启就不生效,如下例子:

所以得将webpack.config.js修改如下:

接下来往babel.config.js添加编译时候需要的loader配置:

3、编写组件
这个是核心部分,就是说这里是你的组件
------------- ./src/index.jsx

------------- ./src/index.less

4、对外暴露组件,编辑根目录下的index.js文件
我这里叫Test,使用组件包引入时候就是Test组件。别人在引用组件包时候会从该文件作为入口(package.json的main字段可以配置),这个文件有两种写法,第一种:

第二种:

5、编写webpack读取的入口文件 public/app.js
webpack启动、编译、打包都会从这个文件作为入口(webpack那边配置的)

6、编写html模板,public/index.html文件。
我们知道spa单页面都是依据一个html模板上面引入js创建虚拟dom生成到这个html上面,所以需要有一个挂载的实例模板。

7、编写.gitignore文件
这个文件可以配置git上传时候忽略哪些文件不想传上去,同时发布组件包的时候它也会按照这个文件来,忽略哪些不上传。

8、添加项目启动命令:修改package.json文件
给该文件的scripts里添加两个系统命令,一个是启动命令,一个是打包命令(制作组件包用的比较少)。注意webpack4的版本可能不是 webpack server --mode development,这个需要自己对应版本。

说明是node版本问题,需要安装高点版本的node,可以使用nvm来管理node版本,这里不多说,我切换为node 12.0.0版本就可以。

到此为止,我们已经配置好了工程,接下来需要把组件包发布上去
1、发布规则

例如你是淘宝源你需要:
查看设置过的所有的源:npm config get registry
设置当前源为npm: npm config set registry https://registry.npmjs.org/
发布完成后设置回淘宝源:npm config set registry https://registry.npm.taobao.org

2、发布流程
1、登录注册好的npm账号:npm login
输入对应的账号、密码、邮箱即可

② React 使用Upload插件上传读取文件内容

某一天,公司里需要一个功能,一个可以把一份参数多如牛毛的配置文件本地存储下来,本地也可以把文件读取出来这样便利的功能。分析一下这个需求,主要就是要以json的格式,保存,和web页面读取json文件的这样两个功能。公司的工程是react编写的,可能对vue和原生js都有一定了解的你,对react并不熟悉,那么,如何解决这个问题

首先,我们假定拿到了一个json格式的变量

那么,再写一个download的工具类

发现问题!直接download下来的是没有格式化过的文本,乱成一团,毫无可读性可言。一个formatjson非常重要!

一行调用!

react有很多轮子,upload当然也有相应封装好的工具,引入!
(在这之前别忘了npm install react-fileupload -save)

写一份配置文件,这个文件中写出的API这边有 https://www.jianshu.com/p/3aa9d5ad41b0

操作在那边已经很清晰啦,我就不多说了

拿到文件之后,当然要把文件内容在web上就解析出来

好啦,fileContent就是里面的内容,json对象,拿到之后,就可以为所欲为了!

③ 利用antd添加文件预览

import styles from './style.scss'; // 自定义样式,文件名称不可修改

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>

    )

}

热点内容
源码输出电视盒 发布:2025-01-13 14:16:54 浏览:172
D算法求矩阵 发布:2025-01-13 14:16:20 浏览:136
商城前端源码 发布:2025-01-13 14:08:43 浏览:48
每个人身上都有密码是什么 发布:2025-01-13 14:08:40 浏览:472
怎么看java 发布:2025-01-13 13:54:18 浏览:10
没脚本导演 发布:2025-01-13 13:52:22 浏览:339
获取android签名 发布:2025-01-13 13:40:21 浏览:595
单片机编译器和驱动 发布:2025-01-13 13:31:33 浏览:440
tis服务器怎么进pe 发布:2025-01-13 13:31:02 浏览:277
android线程与线程通信 发布:2025-01-13 13:30:27 浏览:39