react-data-center
Version:
``` npm install react-data-center --save ``` * react 数据中心模块解决数据统一各模块通信问题 * 支持安全渲染 ## 使用 * 主入口
371 lines (319 loc) • 14.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.saveRender = exports.register = exports.connect = exports.Message = exports.DATA = exports.combine = exports.Com = exports.Provider = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _messageEvent = require('message-event');
var _messageEvent2 = _interopRequireDefault(_messageEvent);
var _data = require('./data');
var _data2 = _interopRequireDefault(_data);
var _safeRender = require('./safe-render');
var _safeRender2 = _interopRequireDefault(_safeRender);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* Created by zhou on 17/3/1
*模块实现原理
*/
var updateKey = Symbol('__UPDATE__ALL__Provider__');
//一个页面内只能使用一次
var DATA = new _data2.default({
update: function update(cb) {
var listens = DATA._listeners[updateKey];
var n = listens && listens.length;
DATA.fire(updateKey, function () {
if (cb) {
n--;
if (n <= 0) {
cb();
}
}
});
}
});
var compoents = {};
/*
*
* <Provider init = {}></Provider>
* */
var storeTypes = {
Data: _react.PropTypes.object.isRequired
};
//不通过这更新影响太大
var Provider = function (_Component) {
_inherits(Provider, _Component);
function Provider(props, conext) {
_classCallCheck(this, Provider);
var _this = _possibleConstructorReturn(this, (Provider.__proto__ || Object.getPrototypeOf(Provider)).call(this, props, conext));
var init = props.init || {};
if (typeof props.init === 'function') {
init = props.init(DATA) || {};
}
if (props.error) {
DATA.error = props.error;
}
if (init && init.initState) {
DATA.state = init.initState;
}
if (props.isSafeRender === false) {
DATA.isSafeRender = false;
}
return _this;
}
_createClass(Provider, [{
key: 'getChildContext',
value: function getChildContext() {
return {
Data: DATA
};
}
}, {
key: 'getData',
value: function getData() {
return DATA;
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: this.props.className },
this.props.children
);
}
}]);
return Provider;
}(_react.Component);
// <Com type="module1"/> 数据从Data模块中获取 要求假设props不动态变化
Provider.defaultProps = {
init: {},
error: false,
isSafeRender: true
};
var Com = function (_Component2) {
_inherits(Com, _Component2);
function Com(props, context) {
_classCallCheck(this, Com);
var _this2 = _possibleConstructorReturn(this, (Com.__proto__ || Object.getPrototypeOf(Com)).call(this, props, context));
_this2.arrUpdate = [];
_this2.moduleObj = DATA.getModule(props.module);
_this2.comp = props.component || _this2.moduleObj.component;
//不可动态修改
_this2.options = Object.assign({ isPure: true, isOnlyFn: false, isSafeRender: null }, props.options || _this2.moduleObj.options || {});
if (typeof _this2.comp === 'string') {
_this2.comp = compoents[_this2.comp];
}
if (!_this2.comp) {
var _ret;
return _ret = console.error('component cannot be null', _this2.moduleObj, props.module), _possibleConstructorReturn(_this2, _ret);
}
if (_this2.options.isSafeRender === true || DATA.isSafeRender !== false && _this2.options.isSafeRender !== false) {
_this2.comp = (0, _safeRender2.default)(_this2.comp, props.error || _this2.moduleObj.error || DATA.error);
}
_this2.state = _this2.getState();
_this2.stateHashCode = _this2.createHashCode(_this2.state);
_this2._update = function (cb) {
if (_this2.didMount) {
_this2.shouldSetState(_this2.getState(), cb);
} else {
_this2.arrUpdate.push(cb);
}
};
//监听
!_this2.options.isOnlyFn && DATA.on(updateKey, _this2._update);
_this2.refObj = {};
//动态ref不考虑
if (props.ref) {
_this2.refObj = { ref: function ref(c) {
_this2.child = c;
} };
}
return _this2;
}
_createClass(Com, [{
key: 'shouldSetState',
value: function shouldSetState(state, cb) {
if (this.isChangeState(state)) {
this.setState(state, cb);
} else {
cb && cb();
}
}
}, {
key: 'getState',
value: function getState() {
var _this3 = this;
var state = this.props.props || this.moduleObj.props || {};
if (typeof state === 'function') {
state = state(DATA) || {};
}
//添加这2方法
state.state = state.state || this.moduleObj.state || {};
if (this.moduleObj && this.moduleObj.setState) {
['fire', 'setState'].forEach(function (key) {
state[key] = state[key] || _this3.moduleObj[key].bind(_this3.moduleObj);
});
}
return state;
}
}, {
key: 'render',
value: function render() {
var Comp = this.comp;
var _props = this.props,
module = _props.module,
ref = _props.ref,
compoent = _props.compoent,
options = _props.options,
state = _props.state,
props = _props.props,
prop = _objectWithoutProperties(_props, ['module', 'ref', 'compoent', 'options', 'state', 'props']); //去除type
return _react2.default.createElement(Comp, _extends({}, this.refObj, this.state, prop));
}
//不比较nextProps 假设 nextProps 不变
}, {
key: 'shouldComponentUpdate',
value: function shouldComponentUpdate(nextProps, nextState) {
if (this.isShouldComponentUpdate === true) {
this.isShouldComponentUpdate = false;
return true;
} else if (this.options.isOnlyFn) {
return false;
} else if (this.options.isPure && !this.isChangeState(nextState, true)) {
return false;
}
return true;
}
}, {
key: 'createHashCode',
value: function createHashCode(state) {
var str = JSON.stringify(state);
var hash = 0,
i = void 0,
chr = void 0,
len = void 0;
if (str.length === 0) return hash;
for (i = 0, len = str.length; i < len; i++) {
chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
}, {
key: 'isChangeState',
value: function isChangeState(state, no) {
//state = state;
var b = false;
var hashState = this.createHashCode(state);
if (this.stateHashCode !== hashState) {
!no && (this.isShouldComponentUpdate = true);
this.stateHashCode = hashState;
b = true;
}
return b;
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var _this4 = this;
this.didMount = true;
var empty = function empty(arr) {
arr.forEach(function (cb) {
return cb && cb();
});
};
//重新更新
if (this.arrUpdate && this.arrUpdate.length) {
var state = this.getState();
this.shouldSetState(state, function () {
empty(_this4.arrUpdate);
});
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
!this.options.isOnlyFn && DATA.off(updateKey, this._update);
}
}]);
return Com;
}(_react.Component);
Com.defaultProps = {
module: ''
};
Com.propsTypes = {
module: _react.PropTypes.string.isRequired
};
;
//兼容模式
var connect = function connect(module) {
var _class, _temp;
//option
var defaultProps = {};
if (typeof module === 'string') {
defaultProps.module = module;
} else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
defaultProps = module;
} else if (typeof module === 'function') {
defaultProps = module(DATA);
} else {
return conole.error('module\u53C2\u6570\u9519\u8BEF' + module);
}
var comp = defaultProps.component || DATA.getModule(defaultProps.module).component;
if (typeof comp === 'string') {
comp = compoents[comp];
}
if (!comp) {
return conole.error('component\u672A\u627E\u5230' + module);
}
var displayName = (comp.name || comp.displayName || 'connect') + 'Connect';
return _temp = _class = function (_Com) {
_inherits(displayName, _Com);
function displayName() {
_classCallCheck(this, displayName);
return _possibleConstructorReturn(this, (displayName.__proto__ || Object.getPrototypeOf(displayName)).apply(this, arguments));
}
return displayName;
}(Com), _class.defaultProps = defaultProps, _temp;
};
var register = function register(obj, com) {
if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') {
compoents = Object.assign(compoents, obj);
} else if (typeof obj === 'string' && typeof com === 'function') {
compoents[obj] = com;
}
return compoents;
};
var combine = function combine() {
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (obj.initState) {
DATA.state = obj.initState;
delete obj.initState;
}
for (var key in obj) {
var item = obj[key] || {};
if (typeof item === 'function') {
item = item(DATA) || {};
}
//提前创建数据
Object.assign(DATA.createModule(key, item.initState), item);
}
return {};
};
//Com 模块模式 比connect使用更简单
exports.Provider = Provider;
exports.Com = Com;
exports.combine = combine;
exports.DATA = DATA;
exports.Message = _messageEvent2.default;
exports.connect = connect;
exports.register = register;
exports.saveRender = _safeRender2.default;