小程序 ---typescript 裝飾器

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

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

看了typescript才發(fā)現(xiàn)是裝飾器 官方文檔如下

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

裝飾器在js中還在建議搜集階段,所以很少人使用,bable 安裝插件也是可以支持的,目前babel編譯器已經(jīng)支持裝飾器了,裝飾器分為5種:類裝飾器 方法裝飾器 訪問器裝飾器 屬性裝飾器 參數(shù)裝飾器

裝飾器,顧名思義就是在裝飾類,看前面的代碼,這個(gè)connect的作用就是為了后面的 class index 這個(gè)類添加一些內(nèi)部屬性和方法,方便組件內(nèi)部引用 添加的這些屬性和方法都是通過傳參過去的 所以組件的壓力沒那么大 都是一些必須要的屬性和方法

這里我們只解析類裝飾器,在taro當(dāng)中tarojs > redux > src里面可以找到connect的源碼大概就是下面這些:為了學(xué)習(xí), 逐行理解

import { getStore } from '../utils/store'  // 從store引入了一個(gè)taro獲得store的方法
import { mergeObjects, isObject } from '../utils' // 引入兩個(gè)方法 深拷貝 和 判斷是否為對象 
export default function connect (mapStateToProps, mapDispatchToProps) {  // 參數(shù)為兩個(gè)方法
  const store = getStore() // 獲取當(dāng)前的store
  const dispatch = store.dispatch // 變量dispatch
  const initMapDispatch = typeof mapDispatchToProps === 'function' ? mapDispatchToProps(dispatch) : {} // 判斷傳入的mapDispatchToProps是否為方法來初始化組件的內(nèi)部方法對象
  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
      }
    })// 這一整個(gè)方法是根據(jù)傳入的參數(shù)初始化state對象, 并且判斷initMapDispatch是否有同名屬性 ,如果有, 進(jìn)行mergeObjects合并

    const isPageHide = this.$root ? this.$root.$isPageHide : this.$isPageHide
    if (isChanged && !isPageHide) {
      this._unsafeCallUpdate = true
      this.setState({}, () => {
        delete this._unsafeCallUpdate
      })
    }
  } // 這個(gè)略過

// 從這里開始才是在編譯時(shí)執(zhí)行的方法 
  return function connectComponent (Component) {   // 這里的Component參數(shù) 就是后面的類
    let unSubscribe = null 
    return class Connect extends Component { // 返回一個(gè)派生類
      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 () { }
    }
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,724評論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,557評論 6 13
  • 本文主要參考自 https://cabbageapps.com/fell-love-js-decorators/。...
    玄魂閱讀 890評論 2 4
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,978評論 1 92
  • 感恩~孩子昨晚睡得很好,今早精神抖擻繼續(xù)以飽滿的熱情去考試。 感恩~伙伴們再一次為孩子做冥想,給予他力量和祝福,在...
    毛毛細(xì)雨mmxy閱讀 141評論 0 0

友情鏈接更多精彩內(nèi)容