當前位置:首頁 » 文件管理 » 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>

    )

}

熱點內容
python中或者怎麼表示 發布:2025-01-13 16:32:33 瀏覽:288
易達加密鎖 發布:2025-01-13 16:27:23 瀏覽:514
前端編譯工具配置 發布:2025-01-13 16:26:43 瀏覽:585
資料庫百度雲 發布:2025-01-13 16:19:38 瀏覽:539
java連接sqlite資料庫 發布:2025-01-13 16:19:36 瀏覽:768
htmlajax上傳文件 發布:2025-01-13 16:19:33 瀏覽:514
安卓怎麼時間顯秒 發布:2025-01-13 16:19:33 瀏覽:474
我的世界java伺服器管理員設置 發布:2025-01-13 16:18:44 瀏覽:493
大秦國之裂變ftp 發布:2025-01-13 15:59:01 瀏覽:371
谷能壓縮機 發布:2025-01-13 15:44:30 瀏覽:413