基于Taro+react自定义弹出层组件|Modal框|Toast轻提示框|dialog对话框|msg信息框|仿微信对话框
taro的旨意是实现多端应用,不过网上大多taro弹窗组件都是针对H5及小程序的,而且一些特殊效果需重新开发,如是自己就试着开发,毕竟之前也有用taro做过自定义导航栏组件。
taro自定义顶部导航栏+底部tabbar菜单
taroPop组件支持自定义弹窗类型(msg/toast/ios/android)/弹窗样式、多按钮事件/按钮样式、自动关闭、遮罩层、弹窗显示位置及自定义内容模板。
支持多参数配置
/**
* @ 弹窗默认配置
*/
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}]
}
在页面引入taroPop弹窗组件
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方式调用组件内show、close方法
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)
}
/**
* 点击遮罩关闭
*/
shadeClick = () => {
if(!this.state.shadeClose) return
this.close()
}
另外还支持自定义弹窗内容模板,只需把页面上的模板写成如下即可,调用方式还和上面一样
...
this.refs.taroPop.show({
content: 'Taro消息提示框(3s后窗口关闭)',
shade: true,
shadeClose: true,
time: 3,
anim: 'fadeIn',
})
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('您点击了前往设置!')
}
}
]
})
let taroPop = this.refs.taroPop
taroPop.show({
skin: 'toast',
content: 'loading',
icon: 'loading', //success | info | error | loading
shade: false,
time: 3
})
对于不同端使用一些兼容性处理,需要判断各端环境并渲染相应模板,对于RN,则使用Modal
let taroEnv = process.env.TARO_ENV
// 渲染窗体
if (taroEnv === 'rn') {
return (
{renderTpl}
)
}else if (taroEnv === 'h5' || taroEnv === 'weapp'){
return isVisible && renderTpl
}
另外对于样式兼容性也需要注意,尤其是编译到reactNative端,各种千奇百怪的问题,有些抓狂~~
/**
* @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, //内容样式
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
}
}
}
到这里就基本介绍差不多了,后续会继续分享一些实践案例~~
最后附上基于vue+uniapp自定义弹窗组件
https://blog.csdn.net/yanxinyun1990/article/details/101594213
https://blog.csdn.net/yanxinyun1990/article/details/102475628