UNPKG

3.35 kBJavaScriptView Raw
1import * as tslib_1 from "tslib";
2/**
3 * @author Kuitos
4 * @homepage https://github.com/kuitos/
5 * @since 2018-05-22 16:39
6 */
7import { Reaction } from 'mobx';
8import Vue from 'vue';
9import collectDataForVue from './collectData';
10// @formatter:off
11// tslint:disable-next-line
12var noop = function () { };
13var disposerSymbol = Symbol('disposerSymbol');
14function observer(Component) {
15 var name = Component.name || Component._componentTag || (Component.constructor && Component.constructor.name) || '<component>';
16 var originalOptions = typeof Component === 'object' ? Component : Component.options;
17 // To not mutate the original component options, we need to construct a new one
18 var dataDefinition = originalOptions.data;
19 var options = tslib_1.__assign({}, originalOptions, { name: name,
20 data: function (vm) {
21 return collectDataForVue(vm || this, dataDefinition);
22 },
23 // overrider the cached constructor to avoid extending skip
24 // @see https://github.com/vuejs/vue/blob/6cc070063bd211229dff5108c99f7d11b6778550/src/core/global-api/extend.js#L24
25 _Ctor: {} });
26 // 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
27 var superProto = typeof Component === 'function' && Object.getPrototypeOf(Component.prototype);
28 var Super = superProto instanceof Vue ? superProto.constructor : Vue;
29 var ExtendedComponent = Super.extend(options);
30 var _a = ExtendedComponent.prototype, $mount = _a.$mount, $destroy = _a.$destroy;
31 ExtendedComponent.prototype.$mount = function () {
32 var _this = this;
33 var args = [];
34 for (var _i = 0; _i < arguments.length; _i++) {
35 args[_i] = arguments[_i];
36 }
37 var mounted = false;
38 this[disposerSymbol] = noop;
39 var nativeRenderOfVue;
40 var reactiveRender = function () {
41 reaction.track(function () {
42 if (!mounted) {
43 $mount.apply(_this, args);
44 mounted = true;
45 nativeRenderOfVue = _this._watcher.getter;
46 // rewrite the native render method of vue with our reactive tracker render
47 // thus if component updated by vue watcher, we could re track and collect dependencies by mobx
48 _this._watcher.getter = reactiveRender;
49 }
50 else {
51 nativeRenderOfVue.call(_this, _this);
52 }
53 });
54 return _this;
55 };
56 var reaction = new Reaction(name + ".render()", reactiveRender);
57 this[disposerSymbol] = reaction.getDisposer();
58 return reactiveRender();
59 };
60 ExtendedComponent.prototype.$destroy = function () {
61 this[disposerSymbol]();
62 $destroy.apply(this);
63 };
64 var extendedComponentNamePropertyDescriptor = Object.getOwnPropertyDescriptor(ExtendedComponent, 'name') || {};
65 if (extendedComponentNamePropertyDescriptor.configurable === true) {
66 Object.defineProperty(ExtendedComponent, 'name', {
67 writable: false,
68 value: name,
69 enumerable: false,
70 configurable: false,
71 });
72 }
73 return ExtendedComponent;
74}
75export { observer, observer as Observer, };