Vue 3 不会检测到对 Vue 组件外部创建的对象所做的更改

2024-01-01

我有一个班级角色:Character.ts

    /// This is called when server responds
    public setAttributeByType(type: StatsTypes, value: number): void {
        switch (type) {
            case StatsTypes.STRENGTH:
            case StatsTypes.DEXTERITY:
            case StatsTypes.VITALITY:
            case StatsTypes.INTELIGENCE:
                this.stats[type] = value;
                break;
            default: break;
        }
    }
    ....

该类实例是在我的“网络代码”中的 Vue 组件外部创建的:

    public static onStartGame(data:any):void {
        Player.character = new Character(data.data);
        Game.displayGamePage(PagesIndex.GAME_PAGE);
        requestAnimationFrame(Game.loop);
    }

并在主要组件中使用:Game.vue

import { defineComponent } from 'vue'
import Player from '@/Player/player';
import SceneManager, { Scenes } from '@/Render/scene_manager';
import Scene from '@/Render/scene';
import MainScene from "@/Render/scenes/main";
import MapScene from "@/Render/scenes/map";
import Game from '@/game/game';

// Components
import VplayerBar from "@/vue/subs/playerBar.vue"
import Vcharacter from "@/vue/subs/character.vue"

export enum GamePages {
    MAIN_PAGE = 1,
    MAP_PAGE,
}

export default defineComponent({
    name: "game",
    components: {
        VplayerBar,
        Vcharacter,
    },
    data() {
        return {
            page: GamePages.MAIN_PAGE,
            scenes: Scenes,
            gamePages: GamePages,
            player: Player,
            character: Player.character, /* <------------ Reference to class */
            pages: {
                character: false,
            }
        }
    },
})

...将其作为支柱传递给character.vue成分

export default defineComponent({
    name: "character",
    props: {
        character: {  // <---- This prop does not change
            type: Character,
            required: true
        },
        toggleCharacter: {
            type: Function, 
            required: true
        }
    },
    components: {
        VBackpack,
        VInventory
    },
    data() {
        return {
            StatsTypes,
        }
    },
    methods: {
        toglePage() {
            this.toggleCharacter()
        },
        getPortrait(isMobile:boolean = false) {
            return Character.getCharacterPortrait(this.character.faction, this.character.gender, isMobile);
        },
        addPoint(attribute:StatsTypes, value: number) {
            if (GKeyHandler.keys[Keys.SHIFT_LEFT])
                value = 10;

            CharacterHandler.addAttributePoint(Player.character, attribute, value);
            //this.character.stats[StatsTypes.STRENGTH] += 1; 
        }
    }
});

问题是,每当我更改 vue 组件之外的字符类实例中的任何内容(在我的网络代码中)时 - 例如character.setAttributeByType(attribute, value),Vue 没有看到变化。如果我直接在里面这样做character.vue组件,它可以工作(请参阅中的注释代码addPoint)

我尝试使用 Proxy & Watch,但没有帮助。


您的问题是描述的“身份”问题here https://v3.vuejs.org/guide/reactivity.html#proxy-vs-original-identity

Vue 3 使用 ES6 代理来使对象具有响应性。如果你这样做const data = reactive(payload), the data那么是不同的对象payload(与 Vue 2 不同,Vue 2 中的对象只是用响应式 setter/getter 进行修改)。

这同样适用于选项 API(您正在使用)。如果你这样做character: Player.character in data()结果是this.character(在 Vue 组件内部)是不同的对象Player.character。您可以通过执行以下操作轻松测试它console.log(this.character === Player.character)...例如在mounted()- 结果将是false

因此,如果您使用进行任何更改this.character(Vue 反应式代理),Vue 将检测更改并重新渲染(并将更改传播到原始对象),但如果更改原始对象Player.characterVue 未检测到更改...

简单的解决方法是使用 Vue 的合成API https://v3.vuejs.org/api/basic-reactivity.html#basic-reactivity-apis它允许您在 Vue 组件之外使用 Vue 反应性。

import { reactive } from `vue`

Player.character = reactive(new Character(data.data));

现在当你使用Player.character初始化data()在 Vue 组件中,Vue 认为它已经是一个响应式代理,并且不再将其包装在代理中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue 3 不会检测到对 Vue 组件外部创建的对象所做的更改 的相关文章

  • 具有相同父布局角度的功能模块路由

    我想使用相同的布局 在应用程序模块 ts 对于不同的功能模块 每个模块都有自己的路由 以及一个单独的登录 注册布局 没有侧面菜单 页眉和页脚 到目前为止我尝试过这个 app app component html
  • angular2存储许多字符串值

    我有一些必须在许多组件中使用的字符串常量值 我不想在各个组件中硬编码或将它们写为字符串 在 Angular2 应用程序中维护它们的最佳位置在哪里 解决方案之一是将字符串放置在共享服务中 将服务注入到需要该属性的每个组件中 如果您的字符串不是
  • 与 webpack 捆绑后,无法读取枚举的未定义属性

    我有一个 React 库 我想使用 Webpack 来构建它 该库是使用 Typescript 编写的 似乎一切正常 但由于某种原因枚举却不起作用 当我将库安装到我的 React 应用程序中时 我发现Cannot read properti
  • 无法使用Vue获取灵活元素的CSS属性值

    我正在尝试获取 CSSwidth灵活元素的属性 但由于某种原因它不起作用 代码笔 https codepen io anon pen pLEwdp editors 1010 https codepen io anon pen pLEwdp
  • Angular 6 http.delete 请求不起作用

    我似乎无法让我的删除请求发挥作用 我已经完成了所有的获取请求 但现在我被困在删除上 似乎无法理解它 console log 的 URL 始终正确 并且删除请求通过 Postman 工作正常 有什么想法吗 HTML
  • 如何强制泛型

    有没有办法在打字稿中将泛型标记为强制 function onSubmit
  • “未知”与“任何”

    TypeScript 3 0 引入unknown根据他们的 wiki 输入 未知现在是保留类型名称 因为它现在是内置类型 根据您对未知的预期用途 您可能需要删除 完全声明 有利于新引入的未知类型 或者 将其重命名为其他名称 有什么区别unk
  • 有没有V型斗篷的反面?

    根据VueJS 文档 https v2 vuejs org v2 api v cloak v cloak 指令可用于隐藏未编译的 Mustache 绑定 直到 Vue 实例准备就绪 换句话说 我可以隐藏一个div或类似的东西 当 vue 准
  • 打字稿标记的枚举获取值

    我在下面标记了枚举 enum PermissionEnum SU 1 lt lt 0 1 Administrator 1 lt lt 1 2 User 1 lt lt 2 4 对于给定值 6 我怎样才能得到 string gt 管理员 用户
  • FontAwesome SVG 图标与 Vuetify - 如何在 v-icon/prepend-icon 中使用?

    我是 Vue 新手 找不到如何在 v icon 和 prepend icon 中使用 FA SVG 图标的确切答案 如果我使用
  • 如何以编程方式启动 Vuetify 对话框并等待响应

    我对 Vue js 和 Vuetify 相当陌生 使用 AngularJS 好几年了 但我们公司正在转向 Vue js 我想要完成的是 当用户单击 登录 按钮时 它会执行一些检查 即用户名不能为空 并启动 Vuetify 对话框来提醒用户
  • Angular 中的文件输入事件类型

    所以我已经使用 Angular 和 Typescript 很长时间了 我似乎无法找出输入文件的类型是什么 例如
  • 未强制执行 Typescript 抽象类静态方法

    我在 TypeScript 中有这个简单的代码 abstract class Config readonly NAME string readonly TITLE string static CoreInterface gt any cla
  • 如何在 Angular @Input 中仅接受预定义值

    我的问题是 我在 a 中收到一个字符串值作为组件的参数 但我想限制可以用作参数的值 就像enum I use Input type string 但是在组件中 一切都可以引入type正如我之前所说 我需要将其限制为 3 个选项 例如Enum
  • 用变量字符串设置槽的简单方法?

    有许多slot例子 但没有克莱尔和简单 因为我需要 我需要类似的东西 var x Hello slot x 这就是我需要的 在一个具体的例子中 https jsfiddle net 2qdh3x3v https jsfiddle net 2
  • Vue中有类似React.Fragment的东西吗?

    在 React 中我可以做这样的事情 parent component export default return div div 1 div div
  • Vue 3 Composition API 提供/注入在单文件组件中不起作用

    我正在使用 Composition API 在 VueJS 3 中创建一个库 我实现了提供 注入 如中所述docs https v3 vuejs org guide composition api provide inject html i
  • 在渲染组件之前从 api 获取数据

    我在渲染页面之前发送 2 个 api 请求 const Profile template profile attributes null photos data function return attributes Profile attr
  • 从回调中访问状态

    我在从回调访问组件状态时遇到问题 国家的价值num更改正确 但此类更改对于加载时定义的回调函数不可见 import React useState from react class MyObject callback gt void cons
  • 使用打字稿的 Angular 6 的黄金布局?

    我在用黄金布局 https golden layout com 与 Angular 6 一起 如下本教程 https npm taobao org package embedded enterprises ng6 golden layout

随机推荐