【问题标题】:Vue variables not reactive in children of extended TypeScript parent classVue 变量在扩展 TypeScript 父类的子类中没有反应
【发布时间】:2019-05-26 22:29:20
【问题描述】:

我最近开始在我的 Vue.js 项目中使用 TypeScript。对于我当前的项目(一个非常简单的聊天应用程序),我创建了一个名为 ChatParent.ts 的 TypeScript 类。它包含发送/接收消息所需的所有方法和变量。我在我的其他组件中扩展了这个类。从这些子类调用父方法可以正常工作,但是,当我监视父类中的变量(例如,username)时,更改不会反映在子组件的 DOM 中。

我尝试添加 setter/getter 方法和计算属性(例如,get methodName(): boolean),但两者都不起作用。

下面的代码来自ChatParent.ts,已经过简化。

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

以下来自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>

每当在subscribe(...) 方法中调用data 回调时,订阅变量都会在父类中更新,但更改不会反映在子组件中(如果subscribe 变量为真)。

我认为我对 Vue + TypeScript 的理解可能完全不正确(关于扩展类)。因此,我非常感谢一些见解。

【问题讨论】:

  • 它只渲染一次,您需要强制重新渲染以更新它,最好的方法是给孩子一个密钥并在父更新时更改密钥,这将迫使孩子重新渲染。看到这里:michaelnthiessen.com/force-re-render

标签: typescript class vue.js


【解决方案1】:

我的猜测是您的某个类中的某些数据可能是未定义的。在这种情况下,您的数据将不会是反应性的(请参阅:https://github.com/vuejs/vue-class-component#undefined-will-not-be-reactive)。你可以尝试使用这种语法,例如username: string = null!

【讨论】:

    【解决方案2】:

    我似乎没有正确理解在 Vue/TypeScript 中扩展类的使用。变量数据不会在所有扩展父类 (ChatParent) 的类之间共享,这就是变量没有触发 DOM 更改的原因。

    我使用Vuex解决了这个问题,如下:

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

    Vuex 存储包含所有变量。 TypeBox.vue 组件现在只需扩展 Vue 并调用存储操作/getter:

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

    可以使用vuex-module-decorators npm 模块将 Vuex 存储操作/getters/mutations 设置为类型安全。

    更多详情,see my GitHub repository

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多