小程序 ---typescript 装饰器

2018-07-06  本文已影响0人  芗芗_

由于本期采用的小程序框架是taro 偶然看到以下写法

@connect(({ counter }) => ({
  counter
}), (dispatch) => ({
  add() {
    dispatch(add())
  }
}))
class Index extends Component {}

看了typescript才发现是装饰器 官方文档如下

https://www.tslang.cn/docs/handbook/decorators.html#class-decorators

装饰器在js中还在建议搜集阶段,所以很少人使用,bable 安装插件也是可以支持的,目前babel编译器已经支持装饰器了,装饰器分为5种:类装饰器 方法装饰器 访问器装饰器 属性装饰器 参数装饰器

装饰器,顾名思义就是在装饰类,看前面的代码,这个connect的作用就是为了后面的 class index 这个类添加一些内部属性和方法,方便组件内部引用 添加的这些属性和方法都是通过传参过去的 所以组件的压力没那么大 都是一些必须要的属性和方法

这里我们只解析类装饰器,在taro当中tarojs > redux > src里面可以找到connect的源码大概就是下面这些:为了学习, 逐行理解

import { getStore } from '../utils/store'  // 从store引入了一个taro获得store的方法
import { mergeObjects, isObject } from '../utils' // 引入两个方法 深拷贝 和 判断是否为对象 
export default function connect (mapStateToProps, mapDispatchToProps) {  // 参数为两个方法
  const store = getStore() // 获取当前的store
  const dispatch = store.dispatch // 变量dispatch
  const initMapDispatch = typeof mapDispatchToProps === 'function' ? mapDispatchToProps(dispatch) : {} // 判断传入的mapDispatchToProps是否为方法来初始化组件的内部方法对象
  initMapDispatch.dispatch = dispatch

  const stateListener = function () {
    let isChanged = false
    const newMapState = mapStateToProps(store.getState())
    Object.keys(newMapState).forEach(key => {
      let val = newMapState[key]
      if (isObject(val) && isObject(initMapDispatch[key])) {
        val = mergeObjects(val, initMapDispatch[key])
      }
      this.prevProps = Object.assign({}, this.props)
      if (this.props[key] !== val) {
        this.props[key] = val
        isChanged = true
      }
    })// 这一整个方法是根据传入的参数初始化state对象, 并且判断initMapDispatch是否有同名属性 ,如果有, 进行mergeObjects合并

    const isPageHide = this.$root ? this.$root.$isPageHide : this.$isPageHide
    if (isChanged && !isPageHide) {
      this._unsafeCallUpdate = true
      this.setState({}, () => {
        delete this._unsafeCallUpdate
      })
    }
  } // 这个略过

// 从这里开始才是在编译时执行的方法 
  return function connectComponent (Component) {   // 这里的Component参数 就是后面的类
    let unSubscribe = null 
    return class Connect extends Component { // 返回一个派生类
      constructor () { // 重写index类的constructor 并为它写入传入的state和方法
        super(Object.assign(...arguments, mergeObjects(mapStateToProps(store.getState()), initMapDispatch)))
        Object.keys(initMapDispatch).forEach(key => {
          this[`__event_${key}`] = initMapDispatch[key]
        })
      }

      componentWillMount () { // 重写componentWillMount 
        const store = getStore()
        Object.assign(this.props, mergeObjects(mapStateToProps(store.getState()), initMapDispatch))
        unSubscribe = store.subscribe(stateListener.bind(this))
        if (super.componentWillMount) {
          super.componentWillMount()
        }
      }
      
      // ... 同理以下都是重写方法
      componentDidShow () {}
      componentDidHide () {}
      componentWillUnmount () { }
    }
  }
}
上一篇下一篇

猜你喜欢

热点阅读