Tips on implementing computed properties in Vue.js while using TypeScript

There is a significant amount of documentation on how to utilize Vue.js with JavaScript, but very little information on using TypeScript. The question arises: how do you create computed properties in a vue component when working with TypeScript?

According to the official example, computed should be an object containing functions that will be cached based on their dependent properties.

Take a look at this example I created:

import Vue from 'vue';
import { Component } from "vue-property-decorator";

@Component({})
export default class ComputedDemo extends Vue {
    private firstName: string = 'John';
    private lastName: string = 'Doe';
    private computed: object = {
        fullName(): string {
            return `${this.firstName} ${this.lastName}`;
        },
    }
}

Here's the accompanying HTML:

<div>
    <h1>Computed props ts demo</h1>
    <ul>
        <li>First name: {{firstName}}</li>
        <li>Last name: {{lastName}}</li>
        <li>Together: {{fullName}}</li>
    </ul>
</div>

The third list item doesn't display anything. Can someone provide guidance on how to properly define computed in this scenario?

Answer №1

If you want to declare computed properties, property accessors are the way to go. Check out Vue Class Component for more information. The getter will be activated as soon as input is entered.

Here's an example:

<template>
    <div>
        <input type="text" name="Test Value" id="" v-model="text">

        <label>{{label}}</label>
    </div>

</template>

<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";

@Component({})
export default class About extends Vue {
    private text = "test";

    get label() {
        return this.text;
    }
}
</script>

Update for Vue Composition Api

<template>
  <div>
    <input type="text" name="Test Value" id v-model="text" />

    <label>{{label}}</label>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed } from "@vue/composition-api";

export default defineComponent({
  setup() {
    const text = ref("test");

    const label = computed(() => {
      return text.value;
    });

    return {
      text,
      label
    };
  }
});
</script>

Answer №2

Vue's declaration files have a circular nature which can create challenges for TypeScript in inferring types for certain methods. To overcome this, it may be necessary to specify the return type for methods like render and those used in computed properties.

import Vue, { VNode } from 'vue'

const Component = Vue.extend({
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    // explicit annotation needed due to `this` in return type
    greet (): string {
      return this.msg + ' world'
    }
  },
  computed: {
    // explicit annotation required
    greeting(): string {
      return this.greet() + '!'
    }
  },
  // `createElement` is inferred, but `render` requires return type
  render (createElement): VNode {
    return createElement('div', this.greeting)
  }
})

If you encounter issues with type inference or member completion, providing annotations for certain methods can help resolve them. Enabling the --noImplicitAny option can assist in identifying many of these unannotated methods.

More Information

Answer №3

Learn Vite Vue 3.2+ with TypeScript

<template>
    <input type="text" v-model="title" />
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { useStore } from 'vuex';

const store = useStore()

const title = computed({
    get: () => store.state.page.about.title,
    set: value => store.commit('setData', { about: { title: value }})
})
</script>

Understanding the setData Mutation in Vuex Store

setData(state: { about: any, blog: any, contact: any, home: any }, data: any) {
     if (data['about']) state.about = { ...state.about, ...data.about }
     if (data['blog']) state.blog = { ...state.blog, ...data.blog }
     if (data['contact']) state.contact = { ...state.contact, ...data.contact }
     if (data['home']) state.home = { ...state.home, ...data.home }
}

The function mentioned above utilizes the spread operator ... to update object fields based on the data passed to it.

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

How to modify the inactive color of a v-switch component in Vuetify

Looking to create a customized v-switch element with Vuetify, specifically aiming for unique colors in both the on and off states. Struggling to achieve the desired visual look, which can be seen here. https://i.stack.imgur.com/k2A2E.png Experimented wit ...

Cannot locate module using absolute paths in React Native with Typescript

I recently initiated a new project and am currently in the process of setting up an absolute path by referencing this informative article: https://medium.com/geekculture/making-life-easier-with-... Despite closely following the steps outlined, I'm en ...

Rendering multiple data in a single cell using Vue.js Template

Hey there, I need some help figuring out how to display this data using Vue.js. I want to show this set of data in a single variable. Any ideas? I attempted to use notification.data.user_id but it's not showing anything on the screen. <div v-for ...

Tips for converting API data to DTO (Data Transfer Object) using TypeScript

Here is an array of vehicles with their details. export const fetchDataFromApi = () => { return [ { vehicleId: 1, vehicleType: 'car', seats: 4, wheelType: 'summer', updatedAt: new Date().toISOString }, { vehicleId: 2, vehic ...

React: Updating a property in an array of objects causes properties to become undefined

My intention was simply to update a property within an object inside an array and then update the state of the array. However, I encountered an issue where all properties except the one that was updated became undefined. The code in question is as follows ...

What is the best way to connect data so that when a user clicks on a specific card, it appears on a popup card

When a user clicks on any card containing data retrieved from a backend API GET method, that data should be displayed in a pop-up card. In my situation, I have two components: DisplayNotes.vue and UpdateNotes.vue. Whenever a user clicks on a displayed card ...

Do you believe this problem with transpilation has been properly reported to babel-jest?

I recently encountered a problem in the jest project regarding babel-jest transpilation. I added some code that appeared to be error-free, but caused transpilation to fail completely. Although the issue seemed related to a Typescript Next project, there a ...

Browser locks up for a brief 4-5 seconds while waiting for the Vue component to complete loading

My Vue components include task.vue, which generates a list of tasks, and epic.vue, the parent of task.vue. Each epic.vue generates its own tasks list from task.vue. The issue arises when the page is reloaded, causing the browser to freeze for 4-5 seconds ...

Error TS2532 in TypeScript indicates that there is a possibility that the object is undefined

Yesterday, WebStorm 2020.1 was installed on my computer. All of a sudden, I started encountering numerous TS2532 errors. How is it even possible for this to be "undefined"? Doesn't selectedOwner && prevent that? I attempted to eliminate thi ...

Youngster listens for guardian's occurrence in Angular 2

While the Angular documentation covers how to listen for child events from parents, my situation is actually the opposite. In my application, I have an 'admin.component' that serves as the layout view for the admin page, including elements such a ...

Toggle visibility of columns in real-time using a bootstrap-vue element alongside Bootstrap 3

Currently, I am attempting to dynamically show/hide elements within a bootstrap-vue table (). Thus far, my efforts have only resulted in hiding the header while the cells remain visible. This creates an issue as the cell placement does not align correctly ...

Unlock exclusive design features from beyond a Component's borders (NativeScript + Vue)

My application is made up of: 6 different components within the component folder, 3 JavaScript files located in the library folder. Within component_1, there is a Layout with a reference called myLayout. One of the JS files, myLayoutHandler, manipulates ...

What is the best way to update the value of a Material Angular select to match its label in TypeScript?

Is there a way to reset the value of this select element back to <mat-label>Select Member</mat-label> in TypeScript when a specific event occurs? I am currently unable to find a solution on the TypeScript side. Any advice would be appreciated ...

What is the best way to integrate model classes within an Angular module?

I have a few classes that I want to keep as plain bean/DTO classes. They are not meant to be display @component classes, @Pipe classes, or @Directive classes (at least, that's what I believe!). I am trying to bundle them into a module so that they ca ...

What could be the reason behind the failure of this computed property to update in my Vue 3 application?

As I transition from Vue's Options API to the Composition API, I decided to create a small Todo App for practice. Within App.vue, my code looks like this: <template> <div id="app"> <ErrorMessage v-if="!isVali ...

Passing events from a parent component to dynamically created child components in Angular

UPDATE: I've decided to tackle this issue in a different way by retrieving dynamic child component values in the parent component's save() function, following the accepted answer. I am attempting to create a system where a parent component emits ...

Troubleshooting Angular 2 Component: Why is console.log not functioning in Typescript?

I'm fairly new to both Angular2 and typescript. Given that typescript is a superset of javascript, I assumed that functions like console.log would function as expected. Interestingly, console.log works perfectly in .ts files when placed outside a comp ...

Error: Angular SSR does not recognize IDBIndex

Attempting to build my Angular application using the command npm run build:ssr. The application built successfully, but when running the command npm run serve:ssr, I encounter the following error: ReferenceError: IDBIndex is not defined Note: Upon invest ...

Display an icon button when a user edits the text in a text field, and make it disappear once clicked on

Figuring out how to incorporate a v-text-area with an added button (icon) that only appears when the text within the text area is edited, and disappears once it is clicked on, has proven to be quite challenging. Below is a simplified version of my code to ...

Generating an array of keys from duplicated values in Typescript

My data is structured in the following array format: { itemTitle: 'value example', itemType: 'value example', itemDescription: 'value example', itemFamily: 'Asset', }, { itemTitle: 'val ...