博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React实现简单易用Toast
阅读量:7187 次
发布时间:2019-06-29

本文共 6186 字,大约阅读时间需要 20 分钟。

效果图

很多项目中需要实现app中常见的提示效果Toast。这个效果看似简单,实现起来也容易,为了方便,将它封装成npm组件,方便后续使用。 这里也是抛砖引玉,可以查看项目地址一起学习

使用方法

import Toast from "react-common-toast";Toast.info("xxx");Toast.info("xxx",duration,onClose);复制代码

组件拆分

  1. 首先是支持多个提示,不同提示定制化也可以不同。取名为Notice。
  2. Notice外面还有个容器组件,用来装载Notice并且,暴露一些方法给Toast,起名Notification,是一个单例。
  3. 最后就是Toast组件,负责直接生成不同的Notice,或者销毁Notification。但是其实Toast只是个对象,而不是真正意义的组件。

Notification

Notification是个容器,里面有一个notice数组。 然后render的时候,循环notices生成一段DOM节点,放到自己的div中。 同时,其还提供一个向notices中添加notice的方法(add)和根据key,在notices中删除notice的方法(remove)。 最后关键的地方,定义一个reRwrite方法,该方法接受一些参数,动态的向DOM中插入一个div,然后再向这个div中插入Notification,最后返回一个含有几个操作这个Notification的方法的对象。(这就是动态实现插入DOM的关键)

// Notification是Notice父组件,容器// 是动态插入和删除DOM节点的核心// 同时也向上暴露给Toast重写改变自己的方法import React from "react";import ReactDOM from "react-dom";import Notice from "./Notice";import "./toast.css";// 统计notice总数 防止重复let noticeNumber = 0;// 生成唯一的idconst getUuid = () => {  return "notification-" + new Date().getTime() + "-" + noticeNumber++;};export default class Notification extends React.Component {   constructor(props) {    super(props);    this.state = {      notices: [], // 存储当前有的notices      hasMask: true // 是否显示蒙版    };  }  add(notice) {    // 添加notice    // 创造一个不重复的key    const { notices } = this.state;    const key = notice.key ? notice.key : (notice.key = getUuid());    const mask = notice.mask ? notice.mask : false;    const temp = notices.filter(item => item.key === key).length;    if (!temp) {      // 不存在重复的 添加      notices.push(notice);      this.setState({        notices: notices,        hasMask: mask      });    }  }  remove(key) {    // 根据key删除对应    this.setState(previousState => {      return {        notices: previousState.notices.filter(notice => notice.key !== key)      };    });  }  getNoticeDOM() {    const _this = this;    const { notices } = this.state;    let result = [];    notices.map(notice => {      // 每个Notice onClose的时候 删除掉notices中对应key的notice      const closeCallback = () => {        _this.remove(notice.key);        // 如果有用户传入的onClose 执行        if (notice.onClose) notice.onClose();      };      result.push(        
); }); return result; } getMaskDOM() { const { notices, hasMask } = this.state; // notices为空的时候 不显示蒙版 // 始终只有一个蒙版 if (notices.length > 0 && hasMask == true) return
; } render() { const noticesDOM = this.getNoticeDOM(); //暂时没有配置蒙版 const maskDOM = this.getMaskDOM(); return (
{/*{maskDOM}*/} {noticesDOM}
); }} // Notification增加一个重写方法 // 该方法方便Notification组件动态添加到页面中和重写Notification.reWrite = properties => { const { ...props } = properties || {}; let div = document.createElement("div"); document.body.appendChild(div); const notification = ReactDOM.render(
, div); return { notice(noticeProps) { notification.add(noticeProps); }, removeNotice(key) { notification.remove(key); }, destroy() { ReactDOM.unmountComponentAtNode(div); document.body.removeChild(div); }, component: notification };};复制代码

Notice

主要是负责接受一些参数,duration,icon,content等等

// Notice是Toast最底层组件// 每个toast的小框框其实都是一个Notice// Notice核心就是组件初始化的时候 生成一个定时器// 根据输入的时间 加载一个动画 然后执行输入的回调// Notice的显示和隐藏收到父组件Notification的绝对控制import React from "react";import classNames from "classnames";import { PropTypes } from "prop-types";export default class Notice extends React.Component {  constructor(props) {    super(props);    this.state = {      shouldClose: false // 是否开启关闭动画    };  }  componentDidMount() {    if (this.props.duration > 0) {      this.closeTimer = setTimeout(() => {        this.close();      }, this.props.duration - 300); // 减掉消失动画300毫秒    }  }  componentWillUnmount() {    // 当有意外关闭的时候 清掉定时器    this.clearCloseTimer();  }  clearCloseTimer() {    if (this.closeTimer) {      clearTimeout(this.closeTimer);      this.closeTimer = null;    }  }  close() {    // 关闭的时候 应该先清掉倒数定时器    // 然后开启过场动画    // 等待动画结束 执行回调    this.clearCloseTimer();    const _this = this;    _this.setState({ shouldClose: true });    this.timer = setTimeout(() => {      if (this.props.onClose) {        this.props.onClose();      }      clearTimeout(_this.timer);    }, 300);  }  render() {    const { shouldClose } = this.state;    return 
{this.props.content}
}}Notice.propTypes = { duration: PropTypes.number, // Notice显示时间 content: PropTypes.any, // Notice显示的内容 onClose: PropTypes.func // 显示结束回调};Notice.defaultProps = { duration: 3000};复制代码

Toast

Toast首先就是要利用Notification.reWrite初始化一个newNotification,并且保持这个Notification为单例。 然后封装一个notice方法,动态的改变这个newNotification。 最后封装几个常用notice方法暴露出去。

import React from "react";import classNames from "classnames";import Notification from "./Notification";// Toast组件比较特殊// 因为
不会被直接渲染在DOM中// 而是动态插入页面中// Toast组件核心就是通过Notification暴露的重写方法 动态改变Notificationlet newNotification;// 获得一个Notificationconst getNewNotification = () => { // 单例 保持页面始终只有一个Notification if (!newNotification) { newNotification = Notification.reWrite(); } return newNotification;};// notice方法实际上就是集合参数 完成对Notification的改变const notice = (content, type, duration = 3000, onClose, mask = true) => { if (!content) return;// content = content.toString(); let notificationInstance = getNewNotification(); notificationInstance.notice({ duration, mask: mask, content: (
{content}
), onClose: () => { if (onClose) onClose(); } });};export default { show(content, duration, icon, mask, onClose) { return notice(content, undefined, icon, duration, onClose, mask); }, info(content, duration, icon, mask, onClose) { return notice(content, "info", icon, duration, onClose, mask); }, success(content, duration, icon, mask, onClose) { return notice(content, "success", icon, duration, onClose, mask); }, warning(content, duration, icon, mask, onClose) { return notice(content, "warning", icon, duration, onClose, mask); }, error(content, duration, icon, mask, onClose) { return notice(content, "error", icon, duration, onClose, mask); }, hide() { if (newNotification) { newNotification.destroy(); newNotification = null; } }};复制代码

转载地址:http://djfkm.baihongyu.com/

你可能感兴趣的文章
二叉树遍历
查看>>
Q3.2 带有最小值或最大值的栈
查看>>
光流法简单介绍
查看>>
Python爬虫小试牛刀
查看>>
SpringMVC.xml配置文件
查看>>
数据和表达式-2
查看>>
python 操作字符串的方法和含义
查看>>
开源免费图表插件
查看>>
JSTL详解
查看>>
寄存器(通用寄存器)
查看>>
服务器模型分析与验证
查看>>
GG's Single Day
查看>>
又回来了,隔了一年了
查看>>
哈夫曼树(Huffman Tree)
查看>>
BAPI
查看>>
模式设计-装饰器模式
查看>>
windows内核驱动中的链表结构
查看>>
POJ3041 Asteroids(最小点覆盖)
查看>>
虚拟化技术:Xen与KVM的对比
查看>>
ASP.NET 之 Chart Control for .Net Framework
查看>>