您的位置:首页 > 移动开发 > 微信开发

Taro自定义Modal对话框组件|taro仿微信、android弹窗

2019-12-02 11:51 190 查看

基于Taro多端实践TaroPop:自定义模态框|dialog对话框|msg消息框|Toast提示

taro自定义弹出框支持编译到多端H5/小程序/ReactNative,还可以自定义弹窗类型/弹窗样式、多按钮事件/样式、自动关闭、遮罩层、弹窗显示位置及自定义内容模板

用法

 ▍在相应页面引入组件

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

通过ref方式调用组件内show、close方法

 this.refs.taroPop.show({...options}) 

 this.refs.taroPop.close() 

 ▍自定义弹窗模板内容(如下图)

只需把页面上的模板写成如下即可,调用方式还和上面一样

<TaroPop ref="taroPopTpl">
...
</TaroPop>

支持多种参数配置:

/**
* @ 弹窗默认配置
*/
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}]
}
/**
* 显示弹窗事件
*/
show = (options) => {
thi
56c
s.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)
}

564
/**
* 点击遮罩关闭
*/
shadeClick = () => {
if(!this.state.shadeClose) return
this.close()
}

◆ msg消息框提示

this.refs.taroPop.show({
content: 'Taro自定义模态Modal弹窗',
shadeClose: false,
style: {backgroundColor: 'rgba(0,0,0,.7)', borderRadius: 6},
contentStyle: {color: '#fff', fontSi
ad8
ze: 12, padding: 12},
time: 3,
opacity: .2,
})

◆ Toast轻提示效果(success | error | info | loading四种图标)

let taroPop = this.refs.taroPop
taroPop.show({
skin: 'toast',
content: 'loading',
icon: 'loading', //success | info | error | loading
shade: false,
time: 3
})

◆ android弹窗效果

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('您点击了前往设置!')
}
}
]
})

emmmm,看了如上展示及调用方式,是否觉得还不错哟!哈哈哈,这可是花了无数个日夜采坑的结果。

尤其是编译到reactNative端,各种千奇百怪的问题,有些抓狂~~

另外对于不同端的一些兼容性处理,需要判断各端环境并渲染相应模板,对于RN,则使用Modal

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
}

另外在样式处理上也需注意RN端兼容性。

/**
* @Title     Taro自定义弹窗组件 - taroPop.js
* @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,     //内容样式

ad8
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: r
ad8
equire('./skin/success.png'),
error: require('./skin/error.png'),
info: require('./skin/info.png'),
}

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'
ad0
&& 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-' + s
56c
kin)} 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') {

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

好了,以上就是taro自定义弹窗组件实现方式,希望能有帮助✊✊~~

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: