🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] * * * * * # 1 模块功能 > Component是界面元素自定义实现。 > Component由props,state控制界面元素 > 通过修改props,state来刷新Component > Component生成vnode,然后由DOM.render()挂载到界面dom中 # 2 模块实现 ## 2.1 Component接口 ~~~ export default class Component { // Component构造函数 constructor(props) { /** @type {object} */ this.props = props || {}; /** @type {object} */ this.state = {}; /** @type {object} */ this.refs = {}; // _blockRender 接受props时状态控制 // _blockSetState 刷新state时状态控制 this._blockRender = false; this._blockSetState = false; this._deferSetState = false; // _pendingSetState 合并state时状态控制 // _pendingState 合并state结果 this._pendingSetState = false; this._pendingState = {}; // _parentNode vnode挂载的父dom节点 // _lastNode 缓存的上次生成的dom节点 this._parentNode = null; this._lastNode = null; // _umounted注册状态 this._unmounted = true; this.context = {}; // _patch() 组件dom刷新接口 this._patch = null; // this._parentComponent = null; this._componentToDOMNodeMap = null; } // 生成Component的虚拟dom结构vnode render() { } // 强制刷新组件 forceUpdate(callback) { if (this._unmounted) { throw Error(noOp); } applyState(this, true, callback); } // 修改组件state,事件处理函数中调用 setState(newState, callback) { if (this._unmounted) { throw Error(noOp); } // 在componentWillUpdate()下 if (this._blockSetState === false) { queueStateChanges(this, newState, callback); } else { throw Error('Inferno Warning: Cannot update state via setState() in componentWillUpdate()'); } } // 挂载完回调接口 componentDidMount() { } // 挂载前回调接口 componentWillMount() { } // 注销前回调接口 componentWillUnmount() { } // props/state刷新后回调接口 applyState() componentDidUpdate() { } // props/state是否更新组件 shouldComponentUpdate() { return true; } // 接受新的props后回调接口 componentWillReceiveProps() { } // props/state刷新前回调接口 componentWillUpdate() { } getChildContext() { } _updateComponent(prevState, nextState, prevProps, nextProps, force) { // 检测是否注销 返回点1 if (this._unmounted === true) { this._unmounted = false; return false; } // props.children获取 if (!isNullOrUndefined(nextProps) && isNullOrUndefined(nextProps.children)) { nextProps.children = prevProps.children; } // props/state比较 if (prevProps !== nextProps || prevState !== nextState || force) { // props不等,接受新的props if (prevProps !== nextProps) { // 接受props时状态控制 this._blockRender = true; this.componentWillReceiveProps(nextProps); this._blockRender = false; // 合并state if (this._pendingSetState) { nextState = Object.assign({}, nextState, this._pendingState); this._pendingSetState = false; this._pendingState = {}; } } // 是否需要刷新组件 const shouldUpdate = this.shouldComponentUpdate(nextProps, nextState); // 需要刷新组件 if (shouldUpdate !== false || force) { // props/state刷新前回调接口 this._blockSetState = true; this.componentWillUpdate(nextProps, nextState); this._blockSetState = false; // 设置props/state this.props = nextProps; this.state = nextState; // 生成新的vnode 返回点2 return this.render(); } } // 不需要重新生成vnode 返回点3 return NO_RENDER; } } ~~~ ## 2.2 助手函数 ~~~ // 获取文档当前焦点节点 function getActiveNode() { return document.activeElement; } // 设置文档当前焦点节点 function resetActiveNode(activeNode) { if (activeNode !== document.body && document.activeElement !== activeNode) { activeNode.focus(); } } // state的更新合并 function queueStateChanges(component, newState, callback) { // 将newstate注册到_pendingState for (let stateKey in newState) { component._pendingState[stateKey] = newState[stateKey]; } // 检查state是否可以刷新 if (!component._pendingSetState) { component._pendingSetState = true; applyState(component, false, callback); } else { component.state = Object.assign({}, component.state, component._pendingState); component._pendingState = {}; } } // state的更新刷新 function applyState(component, force, callback) { if ((!component._deferSetState || force) && !component._blockRender) { component._pendingSetState = false; // 合并state const pendingState = component._pendingState; const prevState = component.state; const nextState = Object.assign({}, prevState, pendingState); // 获取props const props = component.props; // 合并后的state component._pendingState = {}; // 生成新的vnode let nextNode = component._updateComponent(prevState, nextState, props, props, force); // 检查nextNode的NO_RENDER,false返回值 if (nextNode === NO_RENDER) { // nextNode注册为lastNode, nextNode = component._lastNode; } else if (isNullOrUndefined(nextNode)) { // 已注销状态下重新挂载 // nextNode注册为待挂载节点 nextNode = createVPlaceholder(); } // 获取缓存的dom节点lastNode, // 挂载父dome节点 parentDom const lastNode = component._lastNode; const parentDom = lastNode.dom.parentNode; // 获取activeNode,subLifecycle const activeNode = getActiveNode(); const subLifecycle = new Lifecycle(); // 挂载刷新 component._patch(lastNode, nextNode, parentDom, subLifecycle, component.context, component, null); // _lastNode, 缓存本次生成的dom阶段 // _componentToDOMNodeMap compon ent与挂载dom对应 // _parentNode, 挂载的父dom节点 component._lastNode = nextNode; component._componentToDOMNodeMap.set(component, nextNode.dom); component._parentNode.dom = nextNode.dom; // props/state刷新后回调 component.componentDidUpdate(props, prevState); // 调用注册的事件接口 subLifecycle.trigger(); // 回调callback if (!isNullOrUndefined(callback)) { callback(); } // 设置焦点 resetActiveNode(activeNode); } } ~~~ # 3 模块总结 * Component包含由props,state生成的界面元素 * props通常是嵌套父级传递的数据 * state通常是界面操作生成的数据 * Component包含一系列生命周期接口 * ComponentWillMount() mount()前回调 * ComponentDidMount() mount()后回调 * ComponentWillUpdate() state更新前回调 * ComponentDidUpdate() state更新后回调 * ComponentWillReceiveProps() props更新前回调