taojs中! 如何封装一个弹框组件, 灵活方便

一个简单的弹框组件的封装

demo

import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'


import './popper.scss'

interface IProps {
    danger?: boolean,
    title?: string,
    confirmText: string,
    isShowButoon: boolean
}
interface IState {
    isShowDialog: boolean
}

// 定义事件的方法
type Events = 'onConfirm' | 'onCancel' | 'onBackgroundClick' 

type EventCallbackFn = (event: Events) => void

interface Options {
    onEvent: EventCallbackFn
}

export default class Popper extends Component<IProps, IState> {
    //放回私有的方法
    private eventCallback: EventCallbackFn

    //定义一些基本的属性
    static defaultProps = {
        danger: false,
        title: '提示',
        confirmText: '确认',
        isShowButoon: true
    }
    // 定义一些数据
    constructor() {
        super(...arguments)
        this.state = {
            isShowDialog: false
        }
    }

    // 在引用的位置可以调用
    public close() {
        this.setState({
            isShowDialog: false
        })
    }

    public open(options: Options){
        this.setState({
            isShowDialog: true
        })
        this.eventCallback = options.onEvent

    }

    // 私有的方法,只有在内才能调用
    private cancel() {
        this.setState({
            isShowDialog: false
        })
        this.eventCallback('onCancel')
    }

    private confirm() {
        this.setState({
            isShowDialog: false
        })
        this.eventCallback('onConfirm')
    }

    private onBgClick() {
        this.setState({
            isShowDialog: false
        })
        this.eventCallback('onBackgroundClick')
    }

    render () {
        return <View  hidden={!this.state.isShowDialog}>
            <View className='popper-bg' onClick={() => this.onBgClick()}>
                <View className='popper-box' onClick={(e) => e.stopPropagation()}>
                    {/* <View className='popper-title safe safe-boder'>提示</View> */}
                    {/* <View className='popper-title danger danger-boder'>{this.props.title}</View> */}
                    {
                        this.props.danger
                        ? <View className='popper-title danger danger-boder'>{ this.props.title }</View>
                        : <View className='popper-title safe safe-boder'>{this.props.title}</View>
                    }

                    <View className='popper-content'>
                        {this.props.children}
                    </View>
                    { this.props.isShowButoon && <View className='popper-btn'>
                        <View className='cancel' onClick={() => this.cancel()}>取消</View>
                        {/* <View className='confirm safe' onClick={() => this.resolve()}>确认</View> */}
                        {/* <View className='confirm danger' onClick={() => this.confirm()}>确认</View> */}
                        {
                            this.props.danger
                            ? <View className='confirm danger' onClick={() => this.confirm()}>确认</View>
                            : <View className='confirm safe' onClick={() => this.confirm()}>{this.props.confirmText}</View>
                        }
                    </View>}
                </View>
            </View>
        </View>
    }
}

css 部分

.popper-bg {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.6);
    width: 100%;
    z-index: 999;

    .popper-box {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 100px;
        left: 50%;
        margin-left: -169px;
        padding: 0 10px 0px 10px;
        width: 338px;
        // min-height: 175px;
        background-color: #fff;
        z-index: 999;
        box-sizing: border-box;
        border-radius: 4px;

        .popper-title {
            height: 42px;
            line-height: 42px;
        }
        .popper-content {
            flex: 1;
            height: 100%;
            // display: flex;
            // flex-direction: column;
            // align-items: center;
            // justify-content: center;
        }

        .safe {
            color: #009688;
        }
        .safe-boder {
            border-bottom: 2px solid #009688;
        }

        .danger {
            color: #ee5b5b;
        }

        .danger-boder {
            border-bottom: 2px solid #ee5b5b;
        }

        .popper-btn {
            display: flex;
            height: 40px;
            box-sizing: border-box;
            border-top: 1px solid #eee;
            .cancel {
                box-sizing: border-box;
                line-height: 40px;
                text-align: center;
                flex: 1;
                border-right: 1px solid #eee;
            }

            .confirm {
                line-height: 40px;
                text-align: center;
                flex: 1;
            }
        }
    }
}

如何使用

// 1 首先需要引入组件 
import Popper from '@/component/Popper/Popper'

export default class Home extends Component {
  // popper 可以自定义名字
  private popper: Taro.RefObject<Popper>
  constructor() {
    super(...arguments)
    this.state()
    // 个可变ref对象
    this.popper = Taro.createRef<Popper>()
	}
  
  // 当然页面隐藏时,可以关闭背景啦 
  componentDidHide() {
    // 调用close方法即可
    this.popper.current && this.popper.current.close()
	}
 
  change() {
    // 这里可以拿到组件身上的方法
    this.popper.current && this.popper.current.open({
      // 定义的一个对象
      onEvent: (event) {
      	if (event === 'onConfirm') {
      		// 确定按钮事件
   		  } else if (event === 'onCancel') {
          // 取消事件
        } else if (event === 'onBackgroundClick') {
          // 点击背景事件
        }
    }
    })
  }
   
  render() {
    <View className='box'>
     	<View onClick={() => this.change()}></View>
      <Popper ref={this.popper}></Popper>
    </View>
  }
}

posted @ 2019-09-06 17:26  yaogengzhu  阅读(508)  评论(0编辑  收藏  举报