我有一个 Laravel / Vue JS 应用程序,该应用程序集成了google map组件以及 Vuetify数据表组件。 Vue实例还具有计算属性,该属性根据 Vuetify数据表计算出的另一个计算属性,计算Google Map的点。
视图刀片中的Vue组件代码:
<v-data-table :ref="model + 'Table'" v-model="selected" :headers="headers" :items="collection" :pagination.sync="pagination" select-all item-key="id" class="elevation-1" >
</v-data-table>
<google-map v-if="mapPoints.length" class="google-map" :markers="mapPoints"></google-map>
Vue实例代码:
var app = new Vue({
el: '#app',
mixins: [ crudFunctionsMixin, adminLayoutMixin ],
data: () => ({
}),
computed: {
mapPoints: function() {
return this.calcPoints(this.$refs.prospectTable.filteredItems);
}
},
methods: {
calcPoints(items) {
let myPts = [];
let i = 0;
items.forEach(function(prospect) {
if(prospect.latitude && prospect.longitude) {
myPts.push({
id: prospect.id,
position: {
lat: prospect.latitude,
lng: prospect.longitude
},
index: i++,
title: prospect.address + ", " + prospect.city + ", " + prospect.zip,
icon: "\/img\/numberedMapIcons\/number_" + prospect.id + ".png"
});
}
});
return myPts;
}
}
});
这不起作用。它将引发类型错误:
TypeError:无法读取未定义的属性'filteredItems'
这是因为在GoogleMap组件进行评估时, Vuetify数据表组件中的 filteredItems 计算属性尚未计算。
如果我注释掉使用“ points”计算属性的GoogleMap组件,并在页面渲染后使用 Vue JS Devtools 评估points属性,则这些points属性数据计算正确。这是因为在您使用Devtools访问该计算属性之前,不会第一次评估该计算属性,因此该页面已经呈现。因此,“点数”计算属性在页面呈现后的评估结果很好,但当时GoogleMap组件尝试首先对其进行计算。
接下来,如果“ $ refs.prospectTable.filteredItems” 仍未定义,我尝试修改“点”计算属性以返回空数组。
computed: {
mapPoints: function() {
if(!this.$refs.prospectTable)
return [];
else
return this.calcPoints(this.$refs.prospectTable.filteredItems);
}
}
但是,使用此方法时,在定义 $ refs.prospectTable.filteredItems 之前,已计算的属性仅计算一次,因此它返回空数组。即使更改 $ refs.prospectTable.filteredItems 之后,也不会再对计算所得的属性求值。
为什么每次“ $ refs.prospectTable.filteredItems”更改都不会像从未返回初始空数组时一样重新计算“ mapPoints”计算属性?
computed: {
mapPoints: function() {
return this.calcPoints(this.$refs.prospectTable.filteredItems);
}
}
更新:
根据@larizzatg的建议,将 mapPoints 从计算的属性更改为 mount(())内的$ watch变量可以达到目的:
mounted() {
this.$watch(
() => {
return this.$refs.prospectTable.filteredItems;
},
(items) => {
this.mapPoints = this.calcPoints(items);
}
);
}
答案 0 :(得分:1)
创建vue应用后,将执行计算出的属性。在这一点上,该应用程序在真实的dom中没有组件(ref关键字的功能类似于getElementById,因为未定义prostectTable会导致您未定义)
在已安装的生命周期中,组件位于dom中,因此您可以访问参考。代替计算属性,将观察者添加到refspectTable