在 Vuex 模块中添加一个内部管理其状态的复杂对象
Add in a Vuex modules a complex object which manages its status internally
我正在使用 Vuex,作为状态处理程序和工具在我的组件之间共享数据,这些组件不一定 "father-son"。
我想使用 Vuex 共享从外部库获取的复杂对象。
此对象具有更改其属性的方法。
对于这个对象,我不关心集中它的状态,但想要一种在组件之间共享它的方法。
我想到(并放弃)了不同的解决方案:
- 禁用严格模式。但我想把它用于所有其他情况,非常有用!
- 不要使用 Vuex。但它非常方便,而且它与调试工具集成得很好(例如chrome插件)
- 用更简单的商店替换 Vuex:https://austincooper.dev/2019/08/09/vue-observable-state-store。和以前一样的问题
那么,从其他图书馆共享复杂数据的最佳方式是什么?
我想使用 vuex,但我找不到最干净的解决方案!
我的问题的一个例子:
(按获取更多项目,将出现控制台错误)
https://codepen.io/ale-grosselle/pen/dyyxyMr
class Item{
id;
constructor(i){
this.id = Math.round(i * 100);
}
}
//Share collection between the different components
class Collection {
items;
constructor(){
this.items = [new Item(Math.random())];
}
getMore(){
const randomVal = (Math.random());
this.items.push(new Item(randomVal));
}
}
const store = new Vuex.Store({
strict: true,
state: {
collection: new Collection()
},
mutations: {},
getters: {
collection(state) {
return state.collection
}
},
modules: {}
})
new Vue({
el: '#app',
store,
computed: {
collection() {
return this.$store.getters.collection;
}
},
methods: {
addNew() {
this.collection.getMore();
}
}
})
尽管我理解您使用 Vuex 尝试通过您的应用程序共享对象的原因,但我认为这并不是目的,因为 objective 是共享单一数据源通过你的应用程序,你确切地说你不想要(确切地)那个。
如果需要,您可以共享集合 class 的单例实例,由模块导出,并使用 Provide/Inject API.
通过您的应用程序访问它
你会遇到的其他问题(因为我已经尝试在一个项目中做几乎相同的事情)是商店的状态必须是可序列化的,如果你不做任何特殊处理,当您使用 Chrome DevTools 中的 "time travel" 时,您的集合的方法将会丢失(因为状态是使用 JSON.stringify/JSON.parse 序列化和反序列化的)。
我知道这不是您想要的,但 Vuex 似乎不是您希望在您的情况下使用的东西。
编辑:我已经使用上面给出的想法更新了您的示例,并使用 Vue.observable 使对象对 Vue 具有反应性,您可以检查它 here:
class Item {
id;
constructor(i){
this.id = Math.round(i * 100);
}
}
//Share collection between the different components
class Collection {
items;
constructor(){
this.items = [new Item(Math.random())];
}
getMore(){
const randomVal = (Math.random());
this.items.push(new Item(randomVal));
}
}
// Make it observable
const collection = Vue.observable(new Collection());
// Export like a singleton from some module
// export default collection
// provide anywhere on top, for example, in the app itself.
new Vue({
el: '#app',
provide: {
'collection': collection
},
})
// inject anywhere "below" and use it
const ChildComponent = Vue.component('child-component', {
template: `
<button @click='addNew'>Get more items</button>
`,
inject: ['collection'],
methods: {
addNew() {
this.collection.getMore();
}
}
});
// template
<div id='app'>
<pre>{{ collection }}</pre>
<div v-for='item in collection.items'>
{{ item.id }}
</div>
<child-component />
</div>
我正在使用 Vuex,作为状态处理程序和工具在我的组件之间共享数据,这些组件不一定 "father-son"。
我想使用 Vuex 共享从外部库获取的复杂对象。 此对象具有更改其属性的方法。
对于这个对象,我不关心集中它的状态,但想要一种在组件之间共享它的方法。
我想到(并放弃)了不同的解决方案: - 禁用严格模式。但我想把它用于所有其他情况,非常有用! - 不要使用 Vuex。但它非常方便,而且它与调试工具集成得很好(例如chrome插件) - 用更简单的商店替换 Vuex:https://austincooper.dev/2019/08/09/vue-observable-state-store。和以前一样的问题
那么,从其他图书馆共享复杂数据的最佳方式是什么? 我想使用 vuex,但我找不到最干净的解决方案!
我的问题的一个例子: (按获取更多项目,将出现控制台错误) https://codepen.io/ale-grosselle/pen/dyyxyMr
class Item{
id;
constructor(i){
this.id = Math.round(i * 100);
}
}
//Share collection between the different components
class Collection {
items;
constructor(){
this.items = [new Item(Math.random())];
}
getMore(){
const randomVal = (Math.random());
this.items.push(new Item(randomVal));
}
}
const store = new Vuex.Store({
strict: true,
state: {
collection: new Collection()
},
mutations: {},
getters: {
collection(state) {
return state.collection
}
},
modules: {}
})
new Vue({
el: '#app',
store,
computed: {
collection() {
return this.$store.getters.collection;
}
},
methods: {
addNew() {
this.collection.getMore();
}
}
})
尽管我理解您使用 Vuex 尝试通过您的应用程序共享对象的原因,但我认为这并不是目的,因为 objective 是共享单一数据源通过你的应用程序,你确切地说你不想要(确切地)那个。
如果需要,您可以共享集合 class 的单例实例,由模块导出,并使用 Provide/Inject API.
通过您的应用程序访问它你会遇到的其他问题(因为我已经尝试在一个项目中做几乎相同的事情)是商店的状态必须是可序列化的,如果你不做任何特殊处理,当您使用 Chrome DevTools 中的 "time travel" 时,您的集合的方法将会丢失(因为状态是使用 JSON.stringify/JSON.parse 序列化和反序列化的)。
我知道这不是您想要的,但 Vuex 似乎不是您希望在您的情况下使用的东西。
编辑:我已经使用上面给出的想法更新了您的示例,并使用 Vue.observable 使对象对 Vue 具有反应性,您可以检查它 here:
class Item {
id;
constructor(i){
this.id = Math.round(i * 100);
}
}
//Share collection between the different components
class Collection {
items;
constructor(){
this.items = [new Item(Math.random())];
}
getMore(){
const randomVal = (Math.random());
this.items.push(new Item(randomVal));
}
}
// Make it observable
const collection = Vue.observable(new Collection());
// Export like a singleton from some module
// export default collection
// provide anywhere on top, for example, in the app itself.
new Vue({
el: '#app',
provide: {
'collection': collection
},
})
// inject anywhere "below" and use it
const ChildComponent = Vue.component('child-component', {
template: `
<button @click='addNew'>Get more items</button>
`,
inject: ['collection'],
methods: {
addNew() {
this.collection.getMore();
}
}
});
// template
<div id='app'>
<pre>{{ collection }}</pre>
<div v-for='item in collection.items'>
{{ item.id }}
</div>
<child-component />
</div>