Ensuring type signatures are maintained when wrapping Vue computed properties and methods within the Vue.extend constructor

Currently, I am trying to encapsulate all of my defined methods and computed properties within a function that tracks their execution time.

I aim to keep the IntelliSense predictions intact, which are based on the type signature of Vue.extend({...

However, I have struggled to create my own method that can handle the complex type signature without resorting to copying numerous files from the vue.d.ts typings.

Although I have had some success by substituting Vue.extend before invoking it, my preference would be to have my own constructor method with the same typing advantages as Vue's.

Here is an example that works but is bulky, requiring "noImplicitThis": false in .tsconfig:

<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>

My goal is to have a method that replaces Vue.extend, wrapping the computed properties and methods in a chronometer while still maintaining IntelliSense for the component.

As of now, my implementation is cumbersome and requires significant intervention in each component's implementation to be implemented.

Answer №1

As I crafted the example component, I successfully implemented my desired outcome: a single method that incorporates Vue.extend while integrating a timer on specific component methods.

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);
}

Simply use wrap({...componentOptions}) instead of

Vue.extend({...componentOptions})
to activate the timer.

$options may cause issues, but employing a clever workaround seems to prevent errors.

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What causes an AJAX POST request to fail?

While working on a simple HTML page with a form, I encountered an issue with my POST request failing without any response from the server. Can someone please help me figure out what I'm doing wrong? function createRequest(url, body) { var respons ...

Prompt for action following button activation

My goal is to set the focus on an input field when a button is clicked. I am attempting to do this by using a local directive called v-directive. However, I am encountering difficulties in getting the directive to apply properly after the button is clicked ...

Modal Pop-ups Failing to Open on Subsequent Attempts

My table consists of buttons on the right-hand side for a menu. The first button in the menu is supposed to open a modal box upon clicking. However, the first buttons in the subsequent rows do not function as expected and fail to open the modal. Refer to t ...

Is there a similar alternative to {useLocation} provided by 'react-router-dom' that can be used in Next.js?

import { useLocation } from 'react-router-dom'; Currently utilizing Nextjs, I'm seeking assistance in finding an alternative for useLocation ` import Link from 'next/link'; import { FC } from 'react'; import {useRout ...

Bringing in d3js into Angular 2

Is there a way to successfully import d3js into an Angular2 project? I have already installed d3js using npm and added it to my systemJs, but am encountering a traceur.js error. I also attempted to just use the latest cdn in a script tag and tried import * ...

Display HTML content using AJAX within a div element

Within my HTML code, I have the following: <li class="register"><a href="">Registreer</a></li> as well as <div id="content"> </div> I attempted to load an HTML file into the div using the code below in the header se ...

Error code 12030: AJAX request status

When making an ajax XMLHttpRequest using the POST method, I am encountering a readyState of 4 with a status of 12030. It is known that 12030 is a Microsoft-specific state code indicating that the connection was not sustained. However, I have been unable to ...

Retrieving Information from a PHP Backend using Ajax Requests

Just starting out with PHP and eager to learn. I've saved my php file in the www folder on my WAMP server. <?php echo 'Hi'; ?> To run it, I simply go to http://127.0.0.1/testRequestParameter.php in my browser and it displays Hi ...

VueJS: What is the easiest way to create a new instance of a div with just a click of a button?

Is there a way to create a function that will generate a new instance of a specific div (.container in the template) when a button (#addDiv) is clicked, with the button being the only visible element on the webpage initially? I have heard about using docum ...

Determine the central point of the cluster with the most concentrated xy data points

In my project, I have a 200 x 200 square grid where users can vote on the next desired position of an object within this space. Each time a user submits their vote, the XY position is added to an array. Currently, to determine the "winning" position, I ca ...

React component performing AJAX requests

I have a React component that utilizes highcharts-react to display a chart fetched from an API using some of its state properties. export default class CandlestickChart extends React.Component { constructor (props) { super(props); this ...

Utilize apexcharts to apply custom colors for negative data points

I am currently utilizing apex charts within a react application, and I have a requirement to display markers with different colors if the y value is a negative number. Below is the logic that I am using to extract the values: const colorMarkers = ...

Differentiate between function and object types using an enum member

I'm currently experimenting with TypeScript to achieve narrowed types when dealing with index signatures and union types without explicitly discriminating them, such as using a switch case statement. The issue arises in the code snippet below when at ...

Guide to incorporating JavaScript libraries from NPM into a child theme built on Understrap

I am looking to incorporate the Chart Js library within my custom Understrap Child Theme. Instead of simply using a CDN script, which could potentially slow down load times or cause errors if the CDN is not accessible, I have opted to import it into my pac ...

In my development environment, the page does not have scroll functionality, but in the production environment, it is scrollable

Whenever I open a table or any other element with overflowing content, I encounter an issue with the scrolling bar. Even though the CSS includes overflow-y: scroll;, the scroll bar on the right remains in gray and does not allow me to scroll down when the ...

AngularJS ng-repeat items do not properly align when utilizing Bootstrap col-md-2 styles

Utilizing AngularJS ng-repeat for displaying a list of products and incorporating bootstrap col-md-2 to showcase 6 products in each row, I have included a condensed version of my code below: <!DOCTYPE html> <html lang="en"> <head> <ti ...

Finding the index of a chosen option in Angular

Attempting to retrieve the index of the selected option from a select element using Angular. The Angular (4) and Ionic 3 frameworks are being utilized. The template structure is as follows: <ion-select [(ngModel)]="obj.city"> <ion-option ...

How to leverage onpopstate in Vuejs without relying on vue-router

I am currently utilizing vue.js in conjunction with laravel, specifically incorporating a vue component within a laravel blade file. My aim is to trigger a page reload upon pressing the back navigation button to return to the previous page. The code I have ...

Efficiently managing classes with css modules and extractCSS in Nuxt 2

When using Nuxt 2 with CSS modules, I encountered an issue where multiple components resulted in multiple CSS files having the same class. Hello.vue <template> <div :class="$style.title">Hello, World</div> <div :class=&q ...

Issue with Angular: Mobile view toggle button in the navbar is unresponsive

While the dropdowns are functioning correctly in web mode, the navbar toggle isn't working as expected in small screens or mobile mode. I've been trying to figure out the issue by referring to code from CodePen that I am learning from. Despite i ...