mobx-vue
Version:
Vue bindings for MobX
81 lines (80 loc) • 3.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Observer = exports.observer = void 0;
var tslib_1 = require("tslib");
/**
* @author Kuitos
* @homepage https://github.com/kuitos/
* @since 2018-05-22 16:39
*/
var mobx_1 = require("mobx");
var vue_1 = tslib_1.__importDefault(require("vue"));
var collectData_1 = tslib_1.__importDefault(require("./collectData"));
// @formatter:off
// tslint:disable-next-line
var noop = function () { };
var disposerSymbol = Symbol('disposerSymbol');
function observer(Component) {
var name = Component.name || Component._componentTag || (Component.constructor && Component.constructor.name) || '<component>';
var originalOptions = typeof Component === 'object' ? Component : Component.options;
// To not mutate the original component options, we need to construct a new one
var dataDefinition = originalOptions.data;
var options = tslib_1.__assign(tslib_1.__assign({ name: name }, originalOptions), { data: function (vm) {
return collectData_1.default(vm || this, dataDefinition);
},
// overrider the cached constructor to avoid extending skip
// @see https://github.com/vuejs/vue/blob/6cc070063bd211229dff5108c99f7d11b6778550/src/core/global-api/extend.js#L24
_Ctor: {} });
// we couldn't use the Component as super class when Component was a VueClass, that will invoke the lifecycle twice after we called Component.extend
var superProto = typeof Component === 'function' && Object.getPrototypeOf(Component.prototype);
var Super = superProto instanceof vue_1.default ? superProto.constructor : vue_1.default;
var ExtendedComponent = Super.extend(options);
var _a = ExtendedComponent.prototype, $mount = _a.$mount, $destroy = _a.$destroy;
ExtendedComponent.prototype.$mount = function () {
var _this = this;
var _a, _b;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var mounted = false;
this[disposerSymbol] = noop;
var nativeRenderOfVue;
var reactiveRender = function () {
reaction.track(function () {
if (!mounted) {
$mount.apply(_this, args);
mounted = true;
nativeRenderOfVue = _this._watcher.getter;
// rewrite the native render method of vue with our reactive tracker render
// thus if component updated by vue watcher, we could re track and collect dependencies by mobx
_this._watcher.getter = reactiveRender;
}
else {
nativeRenderOfVue.call(_this, _this);
}
});
return _this;
};
var reaction = new mobx_1.Reaction(name + ".render()", reactiveRender);
// @ts-expect-error
this[disposerSymbol] = ((_a = reaction.getDisposer_) === null || _a === void 0 ? void 0 : _a.call(reaction)) || ((_b = reaction.getDisposer) === null || _b === void 0 ? void 0 : _b.call(reaction));
return reactiveRender();
};
ExtendedComponent.prototype.$destroy = function () {
this[disposerSymbol]();
$destroy.apply(this);
};
var extendedComponentNamePropertyDescriptor = Object.getOwnPropertyDescriptor(ExtendedComponent, 'name') || {};
if (extendedComponentNamePropertyDescriptor.configurable === true) {
Object.defineProperty(ExtendedComponent, 'name', {
writable: false,
value: name,
enumerable: false,
configurable: false,
});
}
return ExtendedComponent;
}
exports.observer = observer;
exports.Observer = observer;