Vue 变量在扩展 TypeScript 父类的子类中不反应



我最近开始在我的 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变量为 true,则应该启用文本区域)。

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

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

似乎我没有正确理解在 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 存储操作/getters/mutations 可以通过使用vuex-module-decoratorsnpm 模块进行类型安全。

有关更多详细信息,请参阅我的 GitHub 存储库。

最新更新