UNPKG

mobx-vue

Version:
81 lines (80 loc) 3.78 kB
"use strict"; 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;