saq*_*dev 3 typescript vue.js vuejs3
我有一个类字符:
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;
}
}
....
Run Code Online (Sandbox Code Playgroud)
类实例是在我的“网络代码”中的 Vue 组件之外创建的:
public static onStartGame(data:any):void {
Player.character = new Character(data.data);
Game.displayGamePage(PagesIndex.GAME_PAGE);
requestAnimationFrame(Game.loop);
}
Run Code Online (Sandbox Code Playgroud)
并用于主要组件:
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,
}
}
},
})
Run Code Online (Sandbox Code Playgroud)
...将其作为道具传递给character.vue组件
/// 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;
}
}
....
Run Code Online (Sandbox Code Playgroud)
问题是,每当我在 vue 组件之外(在我的网络代码中)更改字符类实例中的任何内容时,例如character.setAttributeByType(attribute, value),Vue 都看不到更改。如果我直接在character.vue组件内部执行此操作,它会起作用(请参阅 中的注释代码addPoint)
我尝试使用 Proxy & Watch 但它没有帮助。
您的问题是此处描述的“身份”问题
Vue 3 使用 ES6 代理使对象具有反应性。如果你这样做了const data = reactive(payload),那么它data就是不同的对象payload(不像在 Vue 2 中,对象只是用反应式 setter/getter 修改过)。
同样适用于 Options API(您正在使用)。如果你character: Player.character在data()结果是this.character(Vue的组件内)是不同的对象,然后Player.character。您可以通过执行console.log(this.character === Player.character)...轻松测试它,例如在mounted()- 结果将是false
因此,如果您使用this.character(Vue 反应式代理)进行任何更改,Vue 将检测更改并重新渲染(并将更改传播到原始对象),但是如果您更改原始对象Player.character,则 Vue 不会检测到更改...
简单的解决方法是使用 Vue 的Composition API,它允许您在 Vue 组件之外使用 Vue 反应性。
import { reactive } from `vue`
Player.character = reactive(new Character(data.data));
Run Code Online (Sandbox Code Playgroud)
现在当你在 Vue 组件中使用Player.character初始化data()时,Vue 看到它已经是一个响应式代理并且不再将它包装在代理中
| 归档时间: |
|
| 查看次数: |
311 次 |
| 最近记录: |