1. 什么是装饰器
Decorator 是 ES7 的一个新语法,他可以对一些对象进行装饰包装然后返回一个被包装过的对象,可以装饰的对象包括:类,属性,方法等。打个比方:你出去玩,出门前戴了一顶帽子,这是帽子就是装饰器,你自己就是被装饰的对象。
2.装饰器有什么作用
装饰器的作用就是为已经存在的函数或对象添加额外的功能。 装饰器应用场景及理解: 装饰器本质上是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能 它经常用于有切面需求的 场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
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