react.js fetch 基于单例+轻提示(toast)的简单封装

  • Services
/* eslint-disable no-useless-constructor */

import config from './config.js';

import 'whatwg-fetch'
import toast from '../toast/index.js'

export default class Services {
	constructor() { }
	// 单例
	static getInstance() {
		if (!Services.instance) {
			Services.instance = new Services();
			return Services.instance;
		}
		return Services.instance;
	}

	post(action, data) {
		toast.loading("加载中")
		return fetch(config.base_url + action, {
			method: 'POST', // or 'PUT'
			body: JSON.stringify(data),
			headers: {
				'Accept': 'application/json',
				'Content-Type': 'application/json'
			}
		}).then(res => res.json())
	}
	get(action) {

		toast.loading("加载中")
		return fetch(config.base_url + action)
			.then(response => {
				return response.json()
			})
	}
	get1(action) {
		return fetch(action)
			.then(response => {
				return response.json()
			})
	}
}
  • config.js
export default {
       base_url: '请求地址'
}
  • 轻提示
import React from 'react'
import ReactDOM from 'react-dom'
import Toast from './toast'
import './toast.css'

function createNotification() {
    const div = document.createElement('div')
    document.body.appendChild(div)
    const notification = ReactDOM.render( < Toast / > , div)
    return {
        addNotice(notice) {
            return notification.addNotice(notice)
        },
        destroy() {
            ReactDOM.unmountComponentAtNode(div)
            document.body.removeChild(div)
        }
    }
}
let notification
const notice = (type, content, duration = 2000, onClose) => {
    if (!notification) notification = createNotification()
    return notification.addNotice({ type, content, duration, onClose })
}

export default {
    info(content, duration, onClose) {
        return notice('info', content, duration, onClose)
    },
    success(content = '操作成功', duration, onClose) {
        return notice('success', content, duration, onClose)
    },
    error(content, duration, onClose) {
        return notice('error', content, duration, onClose)
    },
    loading(content = '加载中...', duration = 0, onClose) {
        return notice('loading', content, duration, onClose)
    }
}
import React, { Component } from 'react'

class ToastBox extends Component {
    constructor() {
        super()
        this.transitionTime = 300
        this.state = { notices: [] }
        this.removeNotice = this.removeNotice.bind(this)
    }

    getNoticeKey() {
        const { notices } = this.state
        return `notice-${new Date().getTime()}-${notices.length}`
    }

    addNotice(notice) {
        const { notices } = this.state
        notice.key = this.getNoticeKey()

        // notices.push(notice);//展示所有的提示
        notices[0] = notice;//仅展示最后一个提示

        this.setState({ notices })
        if (notice.duration > 0) {
            setTimeout(() => {
                this.removeNotice(notice.key)
            }, notice.duration)
        }
        return () => { this.removeNotice(notice.key) }
    }

    removeNotice(key) {
        const { notices } = this.state
        this.setState({
            notices: notices.filter((notice) => {
                if (notice.key === key) {
                    if (notice.onClose) setTimeout(notice.onClose, this.transitionTime)
                    return false
                }
                return true
            })
        })
    }

    render() {
        const { notices } = this.state
        const icons = {
            info: 'toast_info',
            success: 'toast_success',
            error: 'toast_error',
            loading: 'toast_loading'
        }
        return (
            <div className="toast">
                {
                    notices.map(notice => (
                        <div className="toast_bg" key={notice.key}>
                            <div className='toast_box'>
                                <div className={`toast_icon ${icons[notice.type]}`}></div>
                                <div className='toast_text'>{notice.content}</div>
                            </div>
                        </div>
                    ))
                }
            </div>
        )
    }
}

export default ToastBox
.toast {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 999;
    display: flex;
    flex-direction: column;
}

.toast_bg {
    position: fixed;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
}

.toast_box {
    /*背景框*/
    position: relative;
    left: 32%;
    top: 20%;
    width: 6rem;
    height: 1rem;
    margin: -1rem -1.4rem;
    background: rgba(0, 0, 0, 0.65);
    border-radius: .1rem;
    color: #fff;
}

.toast_text {
    /*文字*/
    position: absolute;
    bottom: 30%;
    text-align: center;
    width: 90%;
    margin: 0 5%;
    height: 0.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.toast_icon {
    /*图标*/
    position: relative;
    left: 10%;
    top: 15%;
    margin: -.4rem;
    width: .8rem;
    height: .8rem;
}


/*content 提示内容 string(loading方法为可选)
duration 提示持续时间 number,单位ms(可选)
onClose 提示关闭时的回调函数(可选)
Toast.error('加载完成',1000,()=>{
 
})
*/

.toast_loading {
    /*Toast.loading('加载完成')*/
    -webkit-animation: loading 1s steps(12, end) infinite;
    animation: loading 1s steps(12, end) infinite;
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAM1BMVEUAAAD///////////////////////////////////////////////////////////////+3leKCAAAAEHRSTlMAENCA8KAgsGDgQMCQUDBwhylaLQAAAL1JREFUOMu9U0kSwyAMK9jsS/T/1zZt2pgEZzq9RBeMZYRGDI/70bO5JptjrOAQVTonIJVK5bW2ma9A7VvpK8OdeQfbZectrDnyU+Oo0b68wGK0muDPdxpOciaizq5pkAgiIPAoew2rBVNYZoM2YHbZDNKz/2Ogam3ff5gMEL8wisfh2KKZiFiGWFkk1B7NSbhNQFy4M2+PghbODNsg7y8THM2njiy8gBgcaEUA9GgNJbxh6fJv+NxiFvYmPAFtCQZNK1qZIAAAAABJRU5ErkJggg==") no-repeat;
    background-size: 100%;
}

.toast_success {
    /*Toast.success('加载完成')*/
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAM1BMVEUAAAD///////////////////////////////////////////////////////////////+3leKCAAAAEHRSTlMA8DAQ0GBP4LCggMBwIJBAIttdjAAAAINJREFUOMvdkUsOwyAMBbH5hUCauf9pK1SlohF438x2LPn52f09+8vUfiNb/gighj8FouEjYCUoQDXiBSD7pdcMiK7XC9wCFmlDO3T20Scgx287ne13pwDU89NOJ3g3maCmJDANqIGRtLj8oi1ed1GMdmcB7wXIYX8QdQZJiM5Em3smbyVICDCOrCqSAAAAAElFTkSuQmCC") no-repeat;
    background-size: 100%;
}

.toast_error {
    /*Toast.error('加载完成')*/
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAMFBMVEUAAAD///////////////////////////////////////////////////////////87TQQwAAAAD3RSTlMA0BDAMODwUKBgsCCAQJClzVPvAAAA0UlEQVQoz2MgErAclv9o44Dgc8b/B4KvBTA+t/3XdgeWivjPG6ACbl8ngNXlp0AN+L8IwtD6DzFm2w+Y3v5sMGW/ACbA9Rms9ZsCTIApH2QR608GhoUKQJ4xA8P8AKCAP5CwF2JgUPwIlPwCFDj/AMRRYJIHCnL8AZkJ1AfkAcUYGNhBpso7MICUgBQw8H4EEv/B5ssDFYA4mAKYWjANfd+Aai3CYZ9BDoM63RDkdEGQ0zE9h+l9zADCDEIGt2/wQEZEwwVepGhgYEdEFGZUEgYAW05XI3jSsVwAAAAASUVORK5CYII=") no-repeat;
    background-size: 100%;
}

.toast_info {
    /*Toast.info('普通提示')*/
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAALVBMVEUAAAD///////////////////////////////////////////////////////+hSKubAAAADnRSTlMA4CCAwKBAMJBg8NAQUNhWlbcAAAC+SURBVCjPYyASsLfse+1cgOBzyr0DgocXYHwmv4dtCkwZck8UoAJZDydA1C2H8NnexUAYR99BjNF6CtMbtwhM+QUACUUhIMH6BKz14QEgafcYSPDIgSxifMkAE2CYJwAk6gQQAozPgURfA0KAA0T6JSAE2ECm7lNACDC9BhLvGGACIA6GAFyLohBEC9xQqLeeQKwFA4i1EIfBAeNzuNMVhSBOx/AcpvcxAwgzCDEDGTMaGHhhEYWIShN4VBIGAPvRT5YzufhUAAAAAElFTkSuQmCC") no-repeat;
    background-size: 100%;
}

@-webkit-keyframes loading {
    0% {
        -webkit-transform: rotate3d(0, 0, 1, 0deg);
        transform: rotate3d(0, 0, 1, 0deg);
    }
    100% {
        -webkit-transform: rotate3d(0, 0, 1, 360deg);
        transform: rotate3d(0, 0, 1, 360deg);
    }
}

@keyframes loading {
    0% {
        -webkit-transform: rotate3d(0, 0, 1, 0deg);
        transform: rotate3d(0, 0, 1, 0deg);
    }
    100% {
        -webkit-transform: rotate3d(0, 0, 1, 360deg);
        transform: rotate3d(0, 0, 1, 360deg);
    }
}
  • 调用
 //post方式
                myservices.getInstance().post("masterlogin",{"account":values.name,"password":values.password})
                .catch(error => {
                    console.error('Error:', error)
                    toast.error("请求失败")
                })
                .then(response => {
                    console.log('Success:', response)
                    // eslint-disable-next-line eqeqeq
                    if(response==undefined){
                     toast.info("登录失败!")
                        
                    }else{
                        toast.success("登录成功!")
                       sessionStorage.setItem("master",JSON.stringify(response.master));
                       this.props.history.push('/home_page');
                    }
 //get方式
                // myservices.getInstance().get(`login?account=${values.name}&password=${values.password}`)
                //.catch(error => console.error('Error:', error))
                // .then(response => console.log('Success:', response));
发布了10 篇原创文章 · 获赞 10 · 访问量 1725

猜你喜欢

转载自blog.csdn.net/lmsfv/article/details/105155547