包装 Vue 计算属性和方法,同时在 Vue.extend 构造函数上保留类型签名
Wrapping Vue computed properties and methods while preserving type signature on Vue.extend constructor
我想将我所有定义的方法和计算的属性包装在一个函数中,该函数为它们的执行计时。
我想保留从 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
到目前为止的结果:一个庞大的实现,需要在每个组件的实现中进行大量干预才能使用
在为此输入示例组件时,我设法实现了我想要的:一个包装 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
},
});
我想将我所有定义的方法和计算的属性包装在一个函数中,该函数为它们的执行计时。
我想保留从 Vue.extend({...
我未能在创建自己的方法的同时维护复杂类型签名,而无需从 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
到目前为止的结果:一个庞大的实现,需要在每个组件的实现中进行大量干预才能使用
在为此输入示例组件时,我设法实现了我想要的:一个包装 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
},
});