包装Vue计算的属性和方法,同时在Vue.extend构造函数上保留类型签名

时间:2019-06-13 20:40:09

标签: javascript typescript vue.js

我想将所有定义的方法和计算出的属性包装在函数中,以对其执行计时。

我想保留从Vue.extend({...的类型签名得出的IntelliSense预测

我无法创建自己的方法,而又无法维护复杂的类型签名,而不必从vue.d.ts键入中复制许多文件。

通过在调用之前替换Vue.extend已经获得了一定的成功,但是我宁愿拥有自己的构造方法,并获得与Vue相同的键入好处。

庞大但有效的示例,该示例在.tsconfig中需要"noImplicitThis": false

<template>
    <div>
        {{ computedValue }}
    </div>
</template>

<script lang="ts">
    import Vue from 'vue';

    const ext = Vue.extend;
    Vue.extend = function (x: any, ...rest:any[]) {
        const f = x.computed.computedValue;
        console.log(x, rest);
        x.computed.computedValue = function () {
            const start = Date.now();
            const rtn = f.call(this, x, ...rest);
            console.log(`Took ${(Date.now() - start) / 1000} seconds`);
            return rtn;
        }
        return ext.call(this, x, ...rest);
    } as any

    const component = Vue.extend({
        computed: {
            computedValue() {
                return 'passed';
            }
        }
    });
    Vue.extend = ext;
    export default component;
</script>

所需结果:代替Vue.extend的方法将在保持组件上的IntelliSense的同时将计算的属性和方法包装在天文钟中

到目前为止的结果:庞大的实现需要对每个组件的实现进行大量干预才能使用

1 个答案:

答案 0 :(得分:0)

为此输入示例组件时,我设法实现了我想要的:一种将Vue.extend包裹在钩子上的计时码表上的单个方法。

import Vue from 'vue';
import { ThisTypedComponentOptionsWithArrayProps } from 'vue/types/options';
import { ExtendedVue } from 'vue/types/vue';

export function wrap<Data, Methods, Computed, PropNames extends string = never>
    (options: ThisTypedComponentOptionsWithArrayProps<Vue, Data, Methods, Computed, PropNames>):
    ExtendedVue<Vue, Data, Methods, Computed, Record<PropNames, any>> {
    if ('computed' in options) {
        Object.keys(options.computed as any).forEach((key: string) => {
            const f: Function = (options.computed as any)[key] as any as Function;
            (options.computed as any)[key] = function (...args: any[]) {
                const start = Date.now();
                const rtn = f.apply(this, args);
                console.log(`${key} took ${(Date.now() - start) / 1000} seconds.`);
                return rtn;
            };
        });
    }
    if ('methods' in options) {
        Object.keys(options.methods as any).forEach((key: string) => {
            const f: Function = (options.methods as any)[key] as any as Function;
            (options.methods as any)[key] = function (...args: any[]) {
                const start = Date.now();
                const rtn = f.apply(this, args);
                console.log(`${key} took ${(Date.now() - start) / 1000} seconds.`);
                return rtn;
            };
        });
    }
    return Vue.extend(options);
}

简单调用wrap({...componentOptions})而不是Vue.extend({...componentOptions}),它将挂上计时器。

$options的玩法不太好,但是偷偷摸摸似乎可以抑制错误

    export default wrap({
        ...{
            a: 4
        },
    });