UNPKG

taro-s4s

Version:

Nerv-multi多端开发解决方案

102 lines (95 loc) 3.02 kB
import { enqueueRender } from './render-queue' import { updateComponent } from './lifecycle' import { internal_safe_get as safeGet } from '@tarojs/taro' // #组件state对应小程序组件data // #私有的__componentProps更新用于触发子组件中对应obsever,生命周期componentWillReciveProps,componentShouldUpdate在这里处理 // #父组件传过来的props放到data.__props中供模板使用,这么做的目的是模拟reciveProps生命周期 // 执行顺序:组件setState -> 组件_createData() -> 对应的小程序组件setData(组件更新)-> 子组件的__componentProps.observer执行 // -> 触发子组件componentWillReciveProps,更新子组件props,componentShouldUpdate -> 子组件_createData -> 子组件setData class BaseComponent { // _createData的时候生成,小程序中通过data.__createData访问 __computed = {} // this.props,小程序中通过data.__props访问 __props = {} __isReady = false // 会在componentDidMount后置为true __mounted = false nextProps = {} _dirty = true _disable = true _pendingStates = [] _pendingCallbacks = [] $router = { params: {} } constructor () { this.state = {} this.props = {} } _constructor (props) { this.props = props || {} } _init (scope) { this.$scope = scope } setState (state, callback) { if (state) { (this._pendingStates = this._pendingStates || []).push(state) } if (typeof callback === 'function') { (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) } if (!this._disable) { enqueueRender(this) } } getState () { const { _pendingStates, state, props } = this const stateClone = Object.assign({}, state) delete stateClone.__data if (!_pendingStates.length) { return stateClone } const queue = _pendingStates.concat() this._pendingStates.length = 0 queue.forEach((nextState) => { if (typeof nextState === 'function') { nextState = nextState.call(this, stateClone, props) } Object.assign(stateClone, nextState) }) return stateClone } forceUpdate (callback) { if (typeof callback === 'function') { (this._pendingCallbacks = this._pendingCallbacks || []).push(callback) } } // 会被匿名函数调用 __triggerPropsFn (key, args) { const keyChain = key.split('.') const reduxFnPrefix = '__event_' const reduxFnName = reduxFnPrefix + keyChain.shift() // redux标识过的方法,直接调用 if (reduxFnName in this) { const scope = args.shift() let fn if (keyChain.length > 0) { fn = safeGet(this[reduxFnName], keyChain.join('.')) } else { fn = this[reduxFnName] } fn.apply(scope, args) } else { // 普通的 const keyLower = key.toLocaleLowerCase() this.$scope.triggerEvent(keyLower, { __isCustomEvt: true, __arguments: args }) } } } export default BaseComponent