我正在构建一个可在同一视图中安装数百甚至数千个vue组件实例的应用程序。每个组件都有一个ID,该ID指向vuex存储中的一个对象。
<my-component :id="item1"></my-component>
<my-component :id="item2"></my-component>
<my-component :id="item3"></my-component>
...
商店:
state: {
myComponentData: [
{
id: 'item1',
name: 'Hawaiian Shirt',
selected: false,
// ...
},
// ...
]
}
在my-component
中,我在存储中查找其对象并将其存储在计算的属性中:
computed: {
myComponentData: function () {
return this.$store.state.myComponentData.find(el => el.id === this.id);
},
isSelected: function () {
return this.myComponentData.selected;
},
// ...
}
可以通过与组件本身或应用程序其他位置的其他组件进行交互来操纵商店中的对象属性。
问题是,当我尝试使用数百个或1000多个元素来运行它时,加载它需要30秒或更长时间。
如果我删除计算出的属性,或将其替换为静态值,则页面将无缝加载。只有当我尝试从商店中加载所有计算的属性时,我才出现滞后问题。
在加载使用计算属性和Vuex的许多(1500+)Vue组件时,是否可以提高性能?我已经研究了动态/异步组件,vue-async-computed和vue-rx作为可能的解决方案,但是我不确定在这种情况下哪种方法有用。
答案 0 :(得分:1)
问题在逻辑内。如果您有1000个项目,则创建1000个组件。然后,它们中的每一个都会在项目列表中循环,以便根据ID找到合适的项目。因此,您基本上正在执行1000 * 1000循环(当然是最坏的情况)。这不是最坏的事情-您正在通过此计算出的属性添加反应性!每次发生更改时,计算方法都会再次触发,从而导致另一个1000循环(如果您的项目是最后一个,则是最坏的情况)。
您有几种选择:
在设置组件中的数据时获取商店的商品。这不会创建计算属性,因此您将拥有静态数据。这将使您自己的个人监视者可以查看要更改的所有数据。
(我会同意这一点)您正在显示该列表的父组件中拥有项目列表。不要只传递ID-传递整个项目。这样,您将不需要使用任何计算出的属性,并且可以立即使用反应性(道具会自动在子代中更新)。
只需添加很少的循环和计算属性-顾名思义,它们用于计算,而不是用于过滤可在其他地方过滤的内容;)
祝你好运!
答案 1 :(得分:1)
我认为Array.find()
操作成本最高。将其包含在计算属性中意味着它会在每次依赖项更改时运行。
您可以在mounted()
中获取数组索引,并在计算出的索引中使用它,
export default {
name: "MyComponent",
props: ["id"],
data() {
return {
storeIndex: -2
};
},
mounted() {
this.storeIndex = this.$store.state.myComponentData.findIndex(
el => el.id == "item" + this.id
);
},
computed: {
myComponentData: function() {
// return this.$store.state.myComponentData.find(
// el => el.id === "item" + this.id
// );
return this.$store.state.myComponentData[this.storeIndex] || {};
},
isSelected: function() {
return this.myComponentData.selected;
}
}
};
这是一个CodeSandbox,上面有一个有效的示例。