react 之裝飾器

1. 什么是裝飾器

   Decorator 是 ES7 的一個新語法,他可以對一些對象進行裝飾包裝然后返回一個被包裝過的對象,可以裝飾的對象包括:類,屬性,方法等。打個比方:你出去玩,出門前戴了一頂帽子,這是帽子就是裝飾器,你自己就是被裝飾的對象。

2.裝飾器有什么作用

   裝飾器的作用就是為已經存在的函數或對象添加額外的功能。 裝飾器應用場景及理解: 裝飾器本質上是一個函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能 它經常用于有切面需求的 場景,比如:插入日志、性能測試、事務處理、緩存、權限校驗等場景。
image

3.裝飾器的應用例子

    這里主要介紹一下類裝飾器,使用類裝飾器可以減少一些代碼的重復編寫。此時裝飾器看起來更像是一個父類,但它又不是一個父類,因為被裝飾的類重寫一些生命周期函數的時候,裝飾器里面的生命周期函數并不會被覆蓋執行。對于componentDidMount 來說,先執被裝飾類的componentDidMount 再執行 裝飾器內的componentDidMount;對于componentWillUnmount 來講先執行裝飾器的componentWillUnmount 再執行被裝飾的類的componentWillUnmount

1) 為所有被裝飾的頁面設置統一的背景色


import React, { Component } from 'react'

export const PageDecorator = param=> WrappedComponent=>{

    return class PageNormal extends Component{

        render(){

            return (

                <div style={{backgroundColor:'rgb(244,245,250)'}}>

                <WrappedComponent {...this.props}></WrappedComponent>

                </div>

            )

        }

    }

}

/*  被裝飾頁面*/

import React, { Component } from 'react'

import {PageDecorator} from '....'  // '...' 內是你的文件路徑

@PageDecorator()

export default  class Page extends Component {

/*.   此處略去一萬行 */

}

如果有的頁面 顏色要求特殊定制怎么辦


/*  裝飾器  PageDecorator*/

import React, { Component } from 'react'

export const PageDecorator = param=> WrappedComponent=>{

    return class PageNormal extends Component{

        render(){

            let bgColor = param && param.background ? param.background : 'rgb(244,245,250)'

            return (

                <div style={{backgroundColor:bgColor}}>

                    <WrappedComponent  {...this.props} ></WrappedComponent>

                </div>

            )

     }

}

/*  被裝飾頁面*/

import React, { Component } from 'react'

import {PageDecorator} from '....'  // '...' 內是你的文件路徑

@PageDecorator({background:'red'})

export default  class Page extends Component {

/*.   此處略去一萬行 */

}

此處只是一個簡單的例子,實際應用中 裝飾器所做的不止是這些,我們可以抽象出某些頁面共同的特點,使用裝飾器創建公共的模版,其他被裝飾的頁面只要實現自己獨特的部分就可以了。

2) 一個裝飾器封裝彈出層的例子


import React, { Component } from 'react'

import { Modal } from 'antd-mobile'

export const ShowModalDecorator = param => WrappedComponent => {

    return class ShowModal extends Component {

        constructor(props) {

            super(props)

            this.state = { show: false, item: {} }

        }

        showModal = item => {

            /****** item 傳入的參數 modal 不需要參數可以不填 *********/

            this.setState({ show: true, item: item })

        }

        hiddenModal = () => {

            this.setState({ show: false })

        }

        render() {

            let props = {

                visible: this.state.show

            }

            // 自定義className 默認的 activityModal 是要自己寫title的

            props.className =

                param && param.className ? param.className : 'activityModal'

            // 是否展示關閉按鈕

            props.closable = param && param.closable ? param.closable : false

            // title

            props.title = param && param.title ? param.title : null

            // 可選: 'slide-down / up' / 'fade' / 'slide'

            props.animationType =

                param && param.animationType ? param.animationType : 'fade'

            //點擊蒙層是否允許關閉

            props.maskClosable =

                param && param.maskClosable ? param.maskClosable : true

            return (

                <Modal

                    transparent

                    {...props}

                    onClose={() => {

                        this.hiddenModal()

                    }}

                >

                    /* 被裝飾的對象,一些參數可以通過props 傳遞*/

                     <WrappedComponent

                        hiddenModal={this.hiddenModal.bind(this)}

                        item={this.state.item}

                        {...this.props}

                    ></WrappedComponent>

                </Modal>

            )

        }

    }

}

后續所有具有相同風格樣式的modal 都可以使用這個modal裝飾


import { ShowModalDecorator } from '..'

@ShowModalDecorator()

export default class SendModal extends Component {

    render() {

        return (

            <div>

                <div>

                    {'你猜猜》》》》》》》》》。。。!'}

                </div>

                <div>

                    <div

                        className="sure"

                        onClick={() => {

                            this.props.hiddenModal()

                        }}

                    >

                        {'確認'}

                    </div>

                </div>

            </div>

        )

    }

}

如果要自定義titile,className 的話 @ShowModalDecorator({title:'彈出層',className:'myClassName'})

這樣 被裝飾的modal 就可以只寫 不一樣的部分了,如果被裝飾的對象需要使用寫在裝飾器內的方法或者數據 通過 props 傳入

被裝飾過 SendModal 該如何使用呢 :

在被使用的地方添加 <SendModal ref={ref => (this.sendModal = ref)}></SendModal>

需要展示的時候 this.sendModal.showModal() 就可以了。

這里有一篇不錯的文章介紹高階組件與裝飾器 : https://www.cnblogs.com/libin-1/p/7087605.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。