-
序
在小程序开发中,我们经常会有这样的需求,需要全局添加一个自定义的弹框,这个弹框可能在任意一个页面中展示,而且这个弹框有着相对复杂的布局与交互,不适合使用微信提供的原生modal,此时,我们要如何添加一个所有页面都公用的弹框,使所有页面都有办法可以调起显示这个弹框呢,以下便来一一分析实现
-
正文
首先,需要实现所有页面共享弹框组件,那么第一时间想到的便是做一个自定义的组件,然后把所有的页面都当做是这个自定义组件的孩子,那么,我们就可以在这个公共的自定义父级组件中增加一些公用的代码,以实现页面布局共享的需求。
其次,实现了布局共享,接下来就需要解决如何让子组件都能够随时调用显示父组件的弹框呢?在这里,我选择使用redux进行公用状态的维护与管理,是所有的页面都可以通过操作redux来控制弹框的显示与隐藏
到此我们便已经实现了我们想要的需求了,光说不练假把式,下面就直接上代码实操吧!
// 公共父级组件:Components/BaseComponent.js
import Taro, {Component} from '@tarojs/taro'
import {View} from '@tarojs/components'
import {AtIcon} from 'taro-ui'
import Theme from '@/utils/theme';
import BaseModal from '../BaseModal'
import {updateModalVisible} from "../../actions/common";
import {modifyUserInfo} from "../../actions/user";
import {connect} from '@tarojs/redux'
@connect(({common}) => {
return {
modals: common.modals
};
}, (dispatch) => ({
updateModalVisible(modals, done) {
dispatch(updateModalVisible(modals, done))
},
modifyUserInfo(userInfo, done) {
dispatch(modifyUserInfo(userInfo, done))
}
}))
class Index extends Component {
constructor(props) {
super(props);
this.state = {
};
}
config = {};
// 此处省略n行无用代码
render() {
let {modals,updateModalVisible,modifyUserInfo} = this.props;
if(modals){
return (
<View className='baseComponent-container'>
{/*页面主体代码都在children中*/}
{this.props.children}
{/*在这里可以添加一下公用的代码,如公共弹框,此处使用的BaseModal是一个自定义弹框组件,不是这次要讲的重点,这里就不贴代码了*/}
<BaseModal
title='提示'
isShow={modals.syncUserInfoModal}
btnClickHandler={(btn,btnIndex,openData)=>{
if(btn.id==='ok'){
// 获取微信用户信息
let {nickName,gender, avatarUrl} = openData.detail.userInfo;
// 调用action同步信息到服务端
modifyUserInfo({
gender: gender===1?'GENDER_MAN':'GENDER_WOMAN',
nickName,
iconUrl: avatarUrl,
wxUserInfo: openData.detail.userInfo
},()=>{
Taro.showToast({
title: '同步成功',
icon: 'success'
});
});
}
}}
onClose={e=>{
// 调用action关闭弹框
updateModalVisible({
syncUserInfoModal: false
});
}}
btns={[
{
id: 'cancel',
text: '容朕想想',
style: {
backgroundColor: Theme.$bgNormal,
color: Theme.$colorStrong
},
click2Close: true
},
{
id: 'ok',
text: '一键同步',
openType:'getUserInfo',
style: {
backgroundColor: Theme.$bgNormal,
color: Theme.$colorBrand
},
click2Close: true
},
]}
>
您尚未完善您的个人信息,是否一键同步微信个人信息?
</BaseModal>
</View>
)
}
}
}
export default Index;
// 引入基础组件的页面组件 index.js
import Taro, {Component} from '@tarojs/taro'
import {View} from '@tarojs/components'
// 引入基础组件
import BaseComponent from '@/components/BaseComponent'
import {connect} from '@tarojs/redux'
//用于显示弹框的action
import {updateModalVisible} from "../../actions/common";
@connect(({common}) => {
return {
};
}, (dispatch) => ({
updateModalVisible(modal) {
dispatch(updateModalVisible(modal))
}
}))
class Index extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount(){
let {updateModalVisible} = this.props;
//显示指定弹框
updateModalVisible({syncUserInfoModal: true});
}
// 此处省略n行无关代码
render() {
return (
<BaseComponent>
<View className='index-container'>
</View>
</BaseComponent>
)
}
}
export default Index;
以下是最终实现效果
相关代码下载: