es6两种装饰器最简单的定义及用法

83 阅读1分钟

记录es6两种装饰器最简单的定义及用法

先弄个简单的自定义事件

function Event(){
    this.callback = {}
}

Event.prototype.on = function (type,cb) {

    this.callback[type] = this.callback[type] || []
    this.callback[type].push(cb)
}

Event.prototype.off = function (type) {
    delete this.callback[type]
}

Event.prototype.trigger = function (type) {
    var arg = arguments
    var name = arguments[0]
    Array.prototype.shift.call(arg)
    var fns = this.callback[name]
    var that = this
    fns && fns.map(function (fn) {
        fn.apply(that,arg)
    })
}

export default new Event()

定义方法装饰器


import event from './event'

export const eventlogger = (topic, param)=>{
    const channelName = param || '/';
    event.on(topic,v=>{
        console.log('事件类型: ', topic);
        console.log('级别: ', channelName);
        console.log('参数: ',v.param)
        console.log('返回值: ', v.ret);
    })

    return function(target, name, descriptor) {
        const fn = descriptor.value;
        descriptor.value = function() {
          let value = fn.apply(this, arguments)
          event.trigger(topic, {ret:value,param:arguments});
          return value
        };
    };
}

定义类装饰器


import React from 'react';

export function elseTo(OldComponent){
    // OldComponent.contextTypes = {
    //   familyName: PropTypes.string
    // }
    class NewComponent extends React.Component {
      render() {
        return (
          <div>
            <h2>此处暂时无业务</h2>
            <OldComponent />
          </div>
        )
      }
    }
    return NewComponent;
}

方法装饰器使用

@eventlogger('setData','add')
add(a, b) {
   return a + b;
}
  
handlePlus = e => {
  //this.props.dispatch(plus(1));
  this.add(2,4)
};

类装饰器使用

@elseTo
class Draggables extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      plusing: false
    };
  }
 
  render() {
    return (
      <Draggable
        axis="x"
        handle=".handle"
        defaultPosition={{x: 0, y: 0}}
        position={null}
        grid={[25, 25]}
        scale={1}
        onStart={this.handleStart}
        onDrag={this.handleDrag}
        onStop={this.handleStop}>
        <div style={{width:'100%',height:'500px'}}>
          <div className="handle">Drag from here</div>
          <div>This readme is really dragging on...</div>
        </div>
      </Draggable>
    );
  }
}

能够输出什么结果请自行尝试,装饰器参数和函数参数的用法是相通的,只要在调用前设置好参数的值,在调用时就是把参数代入到装饰器中生效,反之,当你调用了带有装饰器的方法或者类,再设置参数,那么。。。