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