react+taro多端对话框|仿微信/taro-ui弹窗效果

简介:

taroPop自定义弹层组件|Modal框|dialog对话框|仿微信/ios/android对话框

实现了自定义多种弹窗类型(msg/toast/ios/android)/弹窗样式、支持多个按钮事件/按钮样式、自动关闭、遮罩层、弹窗位置及自定义slot模板

如下图:H5+小程序+ReactNative端效果
_2

支持以下自定义参数配置:

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 (
            <View className="taro-container">
                ...

                {
   /* 弹窗模板 */}
                <TaroPop ref="taroPop" />
            </View>
        );
    }
}

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

  • msg消息框效果
    001360_20191202003234670
    this.refs.taroPop.show({
         
      content: 'Taro消息提示框(3s后窗口关闭)',
      shade: true,
      shadeClose: true,
      time: 3,
      anim: 'fadeIn',
    })
    
  • ios弹窗效果
    011360_20191202003700654

    let taroPop = this.refs.taroPop
    taroPop.show({
         
      skin: 'ios',
      title: '消息提示',
      content: 'ios弹窗效果 (弹窗内容,用于告知当前状态、提示信息和解决方法,描述文字/文案尽量控制在三行内)',
      shadeClose: false,
    
      btns: [
          {
         
              text: '取消',
              style: {
         color: '#6190e8'},
              onClick() {
         
                  taroPop.close()
              }
          },
          {
         
              text: '不再提醒',
              style: {
         color: '#6190e8'},
              onClick() {
         
                  console.log('您点击了前往设置!')
              }
          }
      ]
    })
    

002360_20191202003242861

005360_20191202003321900

006360_20191202003407411

004360_20191202003300101

007360_20191202003415629

012360_20191202003708404

013360_20191202003715308
_3

调用方式和上面一样,不过是不同的参数配置不同而已。

/**
 * @Title     Taro自定义弹窗组件 - taroPop.jsx
 * @Time      andy by 2019-11-28
 */

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)
    }

    ...

    render() {
   
        let {
    isVisible, title, content, contentStyle, style, skin, icon, xclose, shade, shadeClose, opacity, time, end, anim, position, btns } = this.state

        let taroEnv = process.env.TARO_ENV

        ...

        // 渲染H5、RN模板
        const renderTpl = (
            <View className="taroPop">
                {
   /* 遮罩 */}
                {
   shade ? <View className="atpop__ui_mask" style={
   {
   opacity: opacity == '' ? .6 : opacity}} onClick={
   this.shadeClick} /> : null}
                {
   /* 窗体 */}
                <View className="atpop__ui_main">
                    <View className={
   classNames('atpop__ui_child', skin && 'atpop__' + skin, position && 'atpop__ui_child-' + position)} style={
   style}>
                        {
   /* 标题 */}
                        {
   title ? <Text className={
   classNames('atpop__ui_tit', skin && 'atpop__ui_tit-' + skin)}>{
   title}</Text> : null}
                        {
   /* 内容 */}
                        {
   content ? <View className="atpop__ui_cnt">
                            {
   /* toast内容 */}
                            {
   icon && skin === 'toast' ?
                                <View className="atpop__ui_toast">
                                    {
   icon === 'loading' && taroEnv === 'rn' ?
                                    <ActivityIndicator color="rgba(255,255,255,.5)" size={
   24} /> : <Image className={
   classNames('atpop__ui_toast-img', icon=='loading' && 'atpop__ui_toast-img-loading')} src={
   toastIcon[icon]} mode="aspectFit" />
                                    }
                                </View>
                                :
                                null
                            }
                            {
   /* 文本内容 */}
                            <Text className={
   classNames('atpop__ui_cntxt', skin && 'atpop__ui_cntxt-' + skin)} style={
   contentStyle}>{
   content}</Text>
                        </View>
                        :
                        this.props.children
                        }
                        {
   /* 按钮 */}
                        {
   btns ? <View className={
   classNames('atpop__ui_btns', skin && 'atpop__ui_btns-' + skin)}>
                            {
   btns.map((item, i) => {
   
                                return taroEnv === 'rn' ? 
                                <TouchableHighlight className={
   classNames('atpop__ui_btn', skin && 'atpop__ui_btn-' + skin)} activeOpacity={
   1} underlayColor='rgba(200,200,200,.3)' key={
   i} onPress={
   item.onClick}>
                                    <Text className={
   classNames('atpop__ui_btntxt', skin && 'atpop__ui_btntxt-' + skin)} style={
   item.style}>{
   item.text}</Text>
                                </TouchableHighlight>
                                :
                                <View className={
   classNames('atpop__ui_btn', skin && 'atpop__ui_btn-' + skin)} key={
   i} onClick={
   item.onClick}>
                                    <Text className={
   classNames('atpop__ui_btntxt', skin && 'atpop__ui_btntxt-' + skin)} style={
   item.style}>{
   item.text}</Text>
                                </View>
                            })}
                        </View>
                        :
                        null
                        }
                    </View>
                    {
   /* xclose */}
                    {
   xclose ? <View className="atpop__ui_xclose" onClick={
   this.close}><Image className="atpop__ui_xclose-img" src={
   require('./skin/error.png')} mode="aspectFit" /></View> : null}
                </View>
            </View>
        )

        // 渲染窗体
        if (taroEnv === 'rn') {
   
            return (
                <Modal transparent={
   true} visible={
   isVisible} onRequestClose={
   this.close}>
                    {
   renderTpl}
                </Modal>
            )
        }else if (taroEnv === 'h5' || taroEnv === 'weapp'){
   
            return isVisible && renderTpl
        }
    }
}

另外编译到RN需要特别注意样式问题,flex布局及最好使用BEM命名规则。

let taroEnv = process.env.TARO_ENV

// 渲染窗体
if (taroEnv === 'rn') {
   
    return (
        <Modal transparent={
   true} visible={
   isVisible} onRequestClose={
   this.close}>
            {
   renderTpl}
        </Modal>
    )
}else if (taroEnv === 'h5' || taroEnv === 'weapp'){
   
    return isVisible && renderTpl
}

像上面,taro还提供了对于不同端环境变量判断,另外RN端使用到了Modal组件包裹。
到这里就基本介绍完了,后续会继续放送一些分享实例。👦👦

目录
相关文章
|
8天前
|
前端开发 UED 开发者
React 模态对话框 Modal Dialog
本文介绍如何在 React 中实现模态对话框,涵盖基本概念、常见问题及解决方案。模态对话框是一种阻止用户与页面其他部分交互的弹出窗口,常用于显示重要信息或收集输入。通过状态管理控制其显示和隐藏,需注意多组件状态同步、关闭行为一致性及样式冲突等问题。文中还介绍了动画效果和键盘导航支持等进阶功能,帮助开发者提升用户体验并确保代码的可维护性。
102 80
|
1月前
|
前端开发 UED 开发者
React 对话框组件 Dialog
本文详细介绍了如何在 React 中实现一个功能完备的对话框组件(Dialog),包括基本用法、常见问题及其解决方案,并通过代码案例进行说明。从安装依赖到创建组件、添加样式,再到解决关闭按钮失效、背景点击无效、键盘导航等问题,最后还介绍了如何添加动画效果和处理异步关闭操作。希望本文能帮助你在实际开发中更高效地使用 React 对话框组件。
140 75
|
3月前
|
前端开发 数据可视化 JavaScript
🚀打造卓越 UI:2024 年不容错过的 9 个 React UI 组件库✨
本文介绍了2024年最受欢迎的9个React UI组件库,每一个都在设计、功能和定制化上有独特的优势,包括Material UI、Ant Design、Chakra UI等。这些组件库为开发者提供了强大、灵活的工具,可以帮助构建现代化、无障碍且高效的Web应用程序。文章详细分析了每个库的特点、适用场景以及关键功能,帮助开发者在项目中做出最合适的选择,无论是打造企业级仪表板还是时尚的用户界面。
327 6
🚀打造卓越 UI:2024 年不容错过的 9 个 React UI 组件库✨
|
2月前
|
缓存 前端开发 开发者
深入理解React Hooks,打造高效响应式UI
深入理解React Hooks,打造高效响应式UI
42 0
|
4月前
|
前端开发 JavaScript
React技术栈-React UI之ant-design使用入门
关于React技术栈中使用ant-design库的入门教程,包括了创建React应用、搭建开发环境、配置按需加载、编写和运行代码的步骤,以及遇到错误的解决方法。
57 2
React技术栈-React UI之ant-design使用入门
|
5月前
|
小程序 JavaScript
Taro@3.x+Vue@3.x+TS开发微信小程序,使用轮播图
本文介绍了使用 Taro 和 Vue 创建轮播组件的两种方法:一是通过 `&lt;swiper&gt;` 实现,二是利用 Nut UI 的 `&lt;nut-swiper&gt;` 组件实现。
120 1
Taro@3.x+Vue@3.x+TS开发微信小程序,使用轮播图
|
5月前
|
小程序 开发者
Taro@3.x+Vue@3.x+TS开发微信小程序,使用自定义tabBar
本文介绍了如何在Taro项目中实现自定义tabBar。首先,在`app.config.ts`中设置`custom: true`并配置`tabBar`。
215 0
Taro@3.x+Vue@3.x+TS开发微信小程序,使用自定义tabBar
|
4月前
|
传感器 监控 前端开发
WHAT - 通过 react-use 源码学习 React(UI 篇)
WHAT - 通过 react-use 源码学习 React(UI 篇)
|
5月前
|
小程序
Taro@3.x+Vue@3.x+TS开发微信小程序,设置转发分享
本文介绍了Taro中`useShareAppMessage`的使用方法,需在页面配置`enableShareAppMessage: true`并重新编译。
189 0
Taro@3.x+Vue@3.x+TS开发微信小程序,设置转发分享
|
5月前
|
小程序 数据安全/隐私保护
Taro@3.x+Vue@3.x+TS开发微信小程序,网络请求封装
在 `src/http` 目录下创建 `request.ts` 文件,并配置 Taro 的网络请求方法 `Taro.request`,支持多种 HTTP 方法并处理数据加密。
210 0
Taro@3.x+Vue@3.x+TS开发微信小程序,网络请求封装

热门文章

最新文章