在Vue.js中,如果有任何组件更新其数据,有没有办法注册事件?
我的用例:我通过一组Javascript类建模RPG角色。 TCharacter
类有几个可以修改的属性:名称,级别,HP,魔术。虽然" name"是一个简单的字符串," HP"和#34;魔术"是一个自定义类TResource
,它有自己的消费和重新填充规则。
TCharacter
类的实例是事实的来源,我创建了一些Vue组件,这些组件是它的视图。
我在Vue中创建了一个character
组件和一个resource
组件,模糊地这样:
<div class=template id=character>
<input v-model="ch.name">
<resource :attr="ch.magic"></resource>
<resource :attr="ch.hp"></resource>
</div>
<div class="template" id="resource">
you have {{ attr.available }} points
<button @click="attr.consume">X</button>
</div>
<div id="main">
<character :ch="lancelot"></character>
</div>
和javascript:
class TCharacter {
constructor() {
this.name = "Lancelot"
this.hp = new Resource(20)
this.magic = new Resource(10)
}
}
class TResource {
constructor(limit) {
this.available = limit
this.limit = limit
}
consume() {
if (this.available > 0) this.available--;
}
}
let lancelot = new TCharacter()
Vue.component('character', {
template: '#character',
props: ['ch'],
})
Vue.component('resource', {
template: '#resource',
props: ['attr'],
})
new Vue({
el: "#main",
data() { return { lancelot } }
})
(我不确定代码是否完全按照书面形式运作,但希望意图很明确。与此非常相似的东西已经为我工作了。)
现在,我希望每次用户进行修改时将角色对象保存到localstorage:更改其名称,点击消耗魔法点的按钮等。
因此,例如,我希望收到通知,ch.name
的值已更改,因为用户在输入框中键入了某些内容。或者因为用户点击了一个按钮而丢失了一个魔法点。
我可以通过安装character
处理程序检测updated()
组件的更改,该处理程序会在修改DOM时通知我(viz)。但是,在修改子组件resource
时,不会触发此操作。我需要为所有其他组件添加单独的updated()
处理程序。这非常繁琐。
我想象的是一个全局updated()
处理程序,它会在任何组件注册更改时随时触发。或者更好的是,指定update
应该触发组件的子项的方法也会发生变化。
编辑:我已经重写了部分问题,以澄清我想要完成的事情。 有些人已经建议过Vuex。但是,根据我的理解,Vuex强制成为真理的唯一来源 - 我已经拥有单一的事实来源。 Vuex与众不同/更好?
答案 0 :(得分:1)
您需要编写lancelot
的序列化版本才能写出来。您可以使用computed
执行此操作。然后你可以watch
计算出来,看看有什么变化。
或者,您可以 watch
每个特征,并在其发生变化时将其写出来。
class TCharacter {
constructor() {
this.name = "Lancelot"
this.hp = new TResource(20)
this.magic = new TResource(10)
}
}
class TResource {
constructor(limit) {
this.available = limit
this.limit = limit
}
consume() {
if (this.available > 0) this.available--;
}
}
let lancelot = new TCharacter()
Vue.component('character', {
template: '#character',
props: ['ch'],
})
Vue.component('resource', {
template: '#resource',
props: ['attr'],
})
const vm = new Vue({
el: "#main",
data() {
return {
lancelot
}
},
computed: {
serializedLancelot() {
return JSON.stringify(this.lancelot);
}
},
watch: {
serializedLancelot(newValue) {
console.log("Save update:", newValue);
}
}
});
setTimeout(() => {
vm.lancelot.hp.consume();
}, 500);
&#13;
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="main">
</div>
&#13;
答案 1 :(得分:0)
我不确定我是否完全理解用例,但如果我的假设是正确的,您需要根据对象的更新(对象属性的更新)更新组件,因为您可以使用{ {3}}。虽然我不确定您是否仅限于使用其他库
此处作为示例,您可以添加一个名为character
的状态值,该值为object
,类似于
const state = {
character = {};
}
现在你可以使用vuex Vuex来改变这种情况。
commit('set_character', your_new_value)
既然你说你需要根据任何突变来更新所有或部分组件,请使用vuex mutations来监听该对象的任何变异,并更新组件的状态。
store.subscribe(mutation => {
if (mutation.type === 'set_character') {
// do whatever you want here
}
})
以上所有内容仅仅是基于您提到的内容的大纲,但这只是一个启动者,您可能会或可能不想将character
添加到商店的状态中,而只是将这些属性添加到商店中为magic
或hp
。