0

I very recently started playing around with TypeScript on my Vue.js projects. For my current project (a very simple chat application) I have created a TypeScript class called ChatParent.ts. It contains all methods and variables necessary for sending/receiving messages. I extend this class in my other components. Calling the parent methods from these child class works fine, however, when I monitor a variable in the parent class (e.g., username) the change is not reflected in the DOM of the child component.

I have tried adding setter/getter methods and computed properties (e.g., get methodName(): boolean), neither of which works.

The code below is from ChatParent.ts and has been simplified.

@Component({
    name: "ChatParent",
})
 export default class ChatParent extends Vue {
    private chatClient: new ChatClient(...);
    subscribed: boolean = false;

    username: string = "";

    subscribe() {
        const subscriptionRequest = new SubscriptionRequest();
        subscriptionRequest.setUsername(username);

        this.chatClient.subscribe(subscriptionRequest).on("data", data => {
            this.subscribed = true;
        });
    }
    ...
}

The following is from TypeBox.vue.

<template>
    <v-container pa-2>
        <v-textarea
                outline
                label="Type message here..."
                :disabled="!subscribed"
                v-model="message"
        ></v-textarea>
    </v-container>

</template>

<script lang="ts">
    import {Component} from "vue-property-decorator";
    import ChatParent from "@/components/ChatParent.ts";

    @Component({
        name: "TypeBox",
    })
    export default class TypeBox extends ChatParent {
        message : string = "";
    }
</script>

Whenever the data callback is called in the subscribe(...) method, the subscription variable gets updated in the parent class, but the change is not reflected in the child component (where it is supposed to enable the text area if the subscribe variable is true).

I think that my understanding of Vue + TypeScript is perhaps completely incorrect (with regards to extending classes). I would, therefore, really appreciate some insight.

1
  • 1
    It's only rendered once, you would need to force a rerender for it to update, the best way imo is to give the child a key and change the key when the parent updates that will force the child to rerender. see here on that: michaelnthiessen.com/force-re-render Commented May 13, 2019 at 8:06

2 Answers 2

3

My guess is that some data from one of your classes may be undefined .In that case your data won't be reactive (see: https://github.com/vuejs/vue-class-component#undefined-will-not-be-reactive ) . you could try to use this syntax e.g username: string = null!

Sign up to request clarification or add additional context in comments.

Comments

1

It seems I did not understand the use of extending classes in Vue/TypeScript correctly. The variable data is not shared amongst all classes that extend the parent class (ChatParent), which is why the variables did not trigger DOM changes.

I solved this problem by using Vuex as follows:

  class ChatModule extends VuexModule {
  // Variables
  chatClient!: ChatClient;
  subscribed: boolean = false;
  username: string = "";
  messages: string = "";

  // Getters
  get getUsername(): string {
    return this.username;
  }

  get getMessages(): string {
    return this.messages;
  }

  get isSubscribed(): boolean {
    return this.subscribed;
  }

  // Mutations and Actions 
  ...

  export default getModule(ChatModule);
}

The Vuex store contains all the variables. The TypeBox.vue component now simply extends Vue and calls store actions/getters:

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import chat from "@/store/modules/chat";
@Component({
  name: "TypeBox"
})
export default class TypeBox extends Vue {
  private message: string = "";
  clearMessage(): void {
    this.message = "";
  }
  sendMessage(message: string): void {
    chat.sendMessage(message);
  }
  get isSubscribed(): boolean {
    return chat.isSubscribed;
  }
}
</script>

The Vuex store actions/getters/mutations can be made Type Safe by using the vuex-module-decorators npm module.

For more details, see my GitHub repository.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.