基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框

基于React+Taro实现自定义Modal框|dialog对话框|Toast轻提示|msg信息框
支持自定义弹窗类型(msg/toast/ios/android)/弹窗样式、多个按钮事件/按钮样式、自动关闭、遮罩层、弹窗显示位置及自定义slot内容模板

实测H5+小程序+RN端效果如下:
基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第1张图片

自定义参数配置:

/** 
 * @ 弹窗默认配置 
 */
static defaultProps = {
    isVisible: false,       //弹窗显示
    
    title: '',              //标题
    content: '',            //内容
    contentStyle: null,     //内容样式
    style: null,            //自定义弹窗样式
    skin: '',               //弹窗风格
    icon: '',               //弹窗图标
    xclose: false,          //自定义关闭按钮
    
    shade: true,            //遮罩层
    shadeClose: true,       //点击遮罩关闭
    opacity: '',            //遮罩透明度
    time: 0,                //自动关闭时间
    end: null,              //销毁弹窗回调函数
    
    position: '',           //弹窗位置显示
 
    btns: null,             //弹窗按钮 [{...args}, {...args}]
}

用法:
在相应页面引入组件
import TaroPop from '@components/taroPop'

import Taro from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
 
// 引入弹窗组件
import TaroPop from '@components/taroPop'
 
export default class TaroPopDemo extends Taro.Component {
    ...
 
    render() {
        return (
            
                ...
                
                {/* 弹窗模板 */}
                
            
        );
    }
}

通过如下方法调用组件内方法
this.refs.taroPop.show({...options})
this.refs.taroPop.close()

/** 
 * 显示弹窗事件 
 */
show = (options) => {
    this.setState({
        ...this.props, ...options, isVisible: true
    })
}
 
/** 
 * 关闭弹窗事件 
 */
close = () => {
    this.setState({...this.props})
 
    this.timer && clearTimeout(this.timer)
    delete this.timer
 
    typeof this.state.end === 'function' && this.state.end.call(this)
}

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第2张图片
如上图:taroPop还支持自定义slot模板内容,只需将组件如下写法即可,调用方式还和上面一致。


    ...
msg效果展示

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第3张图片

this.refs.taroPop.show({
    content: 'Taro消息提示框(3s后窗口关闭)',
    shade: true,
    shadeClose: true,
    time: 3,
    anim: 'fadeIn',
})
Toast效果展示

支持传入success/error/info/loading四种图标
基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第4张图片

let taroPop = this.refs.taroPop
taroPop.show({
    skin: 'toast',
    content: 'loading',
    icon: 'loading', //success | info | error | loading
    shade: false,
    time: 3
})
微信弹窗效果展示

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第5张图片

let taroPop = this.refs.taroPop
taroPop.show({
    skin: 'android',
    title: '邮件提醒',
    content: '系统检测到你未开启新邮件提醒功能,为了保证新邮件能及时收到提醒,请前往系统 [设置] - [应用] 中开启',
    shadeClose: false,
    
    btns: [
        {
            text: '取消',
            onClick() {
                taroPop.close()
            }
        },
        {
            text: '前往设置',
            style: {color: '#4eca33'},
            onClick() {
                console.log('您点击了前往设置!')
            }
        }
    ]
})

另外还有多按钮效果、显示位置(上、下、左、右)

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第6张图片

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第7张图片

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第8张图片

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第9张图片

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第10张图片

基于Taro多端自定义弹窗组件|Toast/msg/dialog信息框_第11张图片

对于不同端可通过如下环境判断:

let taroEnv = process.env.TARO_ENV
 
// 渲染窗体
if (taroEnv === 'rn') {
    return (
        
            {renderTpl}
        
    )
}else if (taroEnv === 'h5' || taroEnv === 'weapp'){
    return isVisible && renderTpl
}

另外编译到多端也需要注意样式问题,尤其是RN端,容易出现各种样式报错的情况。

/**
 * @Title     Taro自定义弹窗组件 - taroPop.jsx
 * @Time      andy by 2019-11-28
 * @About     Q:282310962  wx:xy190310
 */
 
import Taro from '@tarojs/taro'
import { View, Text, Image } from '@tarojs/components'
import { Modal, ActivityIndicator, TouchableHighlight } from 'react-native'
import classNames from 'classnames'
import './index.scss'
 
export default class TaroPop extends Taro.Component {
    /** 
     * @ 弹窗默认配置 
     */
    static defaultProps = {
        isVisible: false,       //弹窗显示
 
        title: '',              //标题
        content: '',            //内容
        contentStyle: null,     //内容样式
        style: null,            //自定义弹窗样式
        skin: '',               //弹窗风格
        icon: '',               //弹窗图标
        xclose: false,          //自定义关闭按钮
 
        shade: true,            //遮罩层
        shadeClose: true,       //点击遮罩关闭
        opacity: '',            //遮罩透明度
        time: 0,                //自动关闭时间
        end: null,              //销毁弹窗回调函数
 
        anim: 'scaleIn',        //弹窗动画
        position: '',           //弹窗位置显示
 
        btns: null,             //弹窗按钮 [{...args}, {...args}]
    }
 
    constructor(props) {
        super(props)
        this.state = {
            ...this.props,
        }
        this.timer = null
    }
 
 
    /** 
     * @ 显示弹窗事件 
     */
    show = (options) => {
        this.setState({
            ...this.props, ...options, isVisible: true
        })
    }
 
    /** 
     * @ 关闭弹窗事件 
     */
    close = () => {
        this.setState({...this.props})
 
        this.timer && clearTimeout(this.timer)
        delete this.timer
 
        typeof this.state.end === 'function' && this.state.end.call(this)
    }
 
    /** 
     * @ 点击遮罩关闭 
     */
    shadeClick = () => {
        if(!this.state.shadeClose) return
        this.close()
    }
 
    render() {
        let { isVisible, title, content, contentStyle, style, skin, icon, xclose, shade, shadeClose, opacity, time, end, anim, position, btns } = this.state
        
        let toastIcon = {
            loading: require('./skin/loading.png'),
            success: require('./skin/success.png'),
            error: require('./skin/error.png'),
            info: require('./skin/info.png'),
        }
 
        let taroEnv = process.env.TARO_ENV
        
        ...
 
        // 渲染H5、RN模板
        const renderTpl = (
            
                {/* 遮罩 */}
                {shade ?  : null}
                {/* 窗体 */}
                
                    
                        {/* 标题 */}
                        {title ? {title} : null}
                        {/* 内容 */}
                        {content ? 
                            {/* toast内容 */}
                            {icon && skin === 'toast' ?
                                
                                    {icon === 'loading' && taroEnv === 'rn' ?
                                     : 
                                    }
                                
                                :
                                null
                            }
                            {/* 文本内容 */}
                            {content}
                        
                        :
                        this.props.children
                        }
                        {/* 按钮 */}
                        {btns ? 
                            {btns.map((item, i) => {
                                return taroEnv === 'rn' ? 
                                
                                    {item.text}
                                
                                :
                                
                                    {item.text}
                                
                            })}
                        
                        :
                        null
                        }
                    
                    {/* xclose */}
                    {xclose ?  : null}
                
            
        )
 
        // 渲染窗体
        if (taroEnv === 'rn') {
            return (
                
                    {renderTpl}
                
            )
        }else if (taroEnv === 'h5' || taroEnv === 'weapp'){
            return isVisible && renderTpl
        }
    }
}

到这里就基本介绍差不多了,后续也会继续分享一些实例~~~
最后附上两个实战项目:
uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面
Taro多端实现仿微信App聊天室|taro聊天

你可能感兴趣的:(taro)