Using TypeScript with Vue in a non-component-based architecture

Recently, I've been facing a challenge while developing an application. I'm using Vue + Vuetify with typescript, but I'm trying to steer clear of creating a single-page application or using webpack to handle .vue components. My goal is to create multiple pages where I initialize a new Vue instance each time. However, I encountered an issue when I tried to create a new instance with the following code:

import * as Vue from 'Vue';
import axios from 'axios';

<any>window.vue = new Vue({
    el: "#app",
    data: {
        drawer: true,
        mini: false,
        totalItems: 0,
        items: [],
        headers: [,
            {
                text: 'Dessert (100g serving)',
                align: 'left',
                sortable: false,
                value: 'name'
            },
            { text: 'Calories', value: 'calories' },
            { text: 'Fat (g)', value: 'fat' },
        ],

    },
methods: {

    getData() {
        axios.get("http://exmaple1234.com/api/list")
            .then((response) => {
                this.$data["totalItems"] = 1;
                this.$data["items"] = [
                    {
                        value: false,
                        name: 'Frozen Yogurt',
                        calories: 159,
                        fat: 6.0,
                    }
                ];
            })
    }
},
mounted() {
    this.$options.methods["getData"].call("getData");

},
});

In my tsconfig.json file

{
  "compilerOptions": {
    "alwaysStrict": true,
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": true,
    "sourceMap": false,
    "target": "es5",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "lib": [ "es2017", "dom", "dom.iterable" ]
  },
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": true
}

Struggling with the limitations of typescript, I found that I couldn't access this.totalItems, this.items, or call this.getData() in mounted(). However, upon debugging in the browser, I noticed that the "this" object did indeed contain these properties and methods.

I resorted to using $data["property"] and $options.methods["methodName"] to interact with the data, but I'm aware that this may not be the correct approach. After reading Vue documentation on ComponentOptions, which offer solutions like creating interfaces or using vue-class-components, I realized that these methods still rely on components, which I am trying to avoid.

Is there a way to effectively use vue + typescript in my specific scenario? Any tips or advice would be greatly appreciated.

Answer №1

I have incorporated an Interface to define all data attributes and methods. Include this.getData();/

this.$options.methods["getData"].call(this);
and set up a new vue instance.

import * as Vue from 'Vue';
import axios from 'axios';

interface AppInterface extends Vue {
    drawer: boolean,
    mini: boolean,
    totalItems: number,
    items: any,
    headers: any,
    getData (): void
}

var App = {
    el: "#app",
    data: {
        drawer: true,
        mini: false,
        totalItems: 0,
        items: [],
        headers: [{
                text: 'Dessert (100g serving)',
                align: 'left',
                sortable: false,
                value: 'name'
            }, {
                text: 'Calories',
                value: 'calories'
            }, {
                text: 'Fat (g)',
                value: 'fat'
            }
        ]
    },
    methods: {
        getData() {
            axios
                .get("http://exmaple1234.com/api/list")
                .then((response) => {
                    this.$data["totalItems"] = 1;
                    this.$data["items"] = [
                        {
                            value: false,
                            name: 'Frozen Yogurt',
                            calories: 159, 
                            fat: 6.0
                        }
                    ];  
                })
        }
    },
    mounted() {
        // or this.$options.methods["getData"].call(this);
        this.getData();
    }
} as Vue.ComponentOptions<AppInterface>

// create a new vue instance
new Vue(App);

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

Exploring the concept of data sharing in the latest version of Next.JS - Server

When using App Router in Next.JS 13 Server Components, the challenge arises of not being able to use context. What would be the most effective method for sharing data between various server components? I have a main layout.tsx along with several nested la ...

"Encountering a 'Module Not Found' error in Node.js after

Recently, I added a node-module to my project using the command: npm install typescript --save-dev However, when I tried running: tsc Windows displayed an error message indicating that "tsc" is an unknown command. Strangely, this issue does not occur o ...

Validation with vee-validate performed instantly after inputting every character

Is it possible to validate after each input character instead of only upon clicking somewhere? Please enter your password: <div class='form-group' :class='{"form-group_invalid": errors.has("password") && error ...

The VueJS front-end is left waiting for a response from the NodeJS backend that never

Having some trouble setting up a login feature in my web application. The backend is using a MongoDB database and NodeJS (express), while the front-end uses VueJS. However, I'm facing an issue where the response from the backend isn't reaching th ...

Issue with DevExtreme nested table not expanding when sorting the parent table

Utilizing the DevExtreme Nested Data Grid (dx-data-grid) within an Angular app to exhibit hierarchical data is proving challenging for me. The data structure comprises a parent table, where each row can have child rows, which in turn can have grandchild ro ...

Placing a MongoDB query results in an increase of roughly 120MB in the total JS heap size

I'm puzzled by the fact that the heap size increases when I include a MongoDB database query in a function within my controller. Here is the code for my router: import { Router } from "express"; import profileController from '../contro ...

What is the best way to send information to a child component that has been navigated from a parent component

When navigating to a child component from the parent component's HTML template using a button, how can I pass the parent component's data (such as a name) to the child component without displaying it in the URL? ...

Using Vue Router's `push()` method within an asynchronous function will solely modify the URL address

I created a custom loading component that displays while the route is being changed. To ensure the loading component properly waits for a second, the method needs to be asynchronous. However, since implementing this feature, I noticed that the router.push ...

Resources for Vue.js stylesheets

Vue.js is my latest discovery and I have been experimenting with the single file component architecture. A small issue I encountered was that all of my components' styles were being loaded on the page, even if they weren't currently active. Is t ...

Vue shared component interacting with various parent components

I am curious about the best practice for communication between Vue.js common components and different parent components. For instance, in my situation, I have a basic modal component that needs to trigger a 'close' method, but it is being used by ...

Different combinations of fields in Typescript types

Take a look at this defined type: type MyType = | { a: number } | { b: number } | { c: number } | ({ b: number } & { c: number }); The goal is to prevent the combination of 'a' with either 'b' or 'c'. const o1: ...

The lib.dom.d.ts file is seriously lacking in many key components

Are there any updated versions of lib.dom.d.ts? The current one is missing a lot of essential information, causing numerous compilation errors. For example, consider this line: window.File && window.FileReader && window.FileList && ...

What is the significance of the source element in Vue3's audio element?

Playing mp3 files works in Vue 2, but not in Vue3. <template> <audio src="../file_example_MP3_700KB.mp3" controls ></audio> </template> In Vue3, the code needs to be modified as follows: <template> <audi ...

What can I do to condense the length of b-dropdown-item-button or make the text wrap instead?

DropDown Currently, I am utilizing Bootstrap-vue. My goal is to ensure that the b-dropdown-item-button wraps the text it displays. Is there a recommended approach for achieving this? <template> <b-dropdown menu-class="py-1" text="··· Action ...

Issue: Transition of FCM to HTTP v1 API from Previous Legacy API

Recently, I have been working on migrating FCM from the legacy API to the HTTP V1 API. Here's a comparison of the "working code before" and after the necessary modifications: Before: const payload = { data: ...

Verification reset post form submission

I have a form with checkboxes and I need the user to choose at least one of them. Everything is working correctly, but when resetting the form, I am unable to hide the validation message. The issue is outlined in detail in the documentation, however, the s ...

Update the input field's placeholder with the current date

Is it possible to dynamically set the placeholders for <input type='date' placeholder='{{ 'currentDate' }}'>? I have tried using the following variable: currentDate = this.datePipe.transform(new Date(), "yyyy-MM-dd& ...

What is the best way to apply variables from a SCSS file to functions within a .vue file?

After following the steps provided in this link, I have successfully configured sass for my project. First, I installed sass using npm install -D sass-loader sass. Next, I created a file named variables.scss under the src directory: src/variables.scss $ ...

Sending state information through props in a Vuex environment

One of the challenges I am facing is how to make a reusable component that can display data from the store. My idea is to pass the name of the store module and property name through props, as shown below: <thingy module="module1" section=" ...

What is the process for constructing and compiling a Vue component for utilization at runtime within Vue?

I'm currently working on a small component that I have uploaded to GitHub at: https://github.com/pksorensen/vue-library-build-issue import Vue, { VNode } from 'vue'; import * as tsx from "vue-tsx-support"; import { Component, Prop, Watch } ...