我想在文本框中搜索并通过属性是否与输入的文本匹配来过滤对象列表。
filteredBuildings 数组中的每个对象都会在 Google 地图上创建一个形状。
我的 Vue 应用程序中有以下内容:
...
data: {
searchtext: '',
buildings: [
{
name: 'Home',
...
},{
name: 'Work',
...
}
],
},
computed: {
filteredBuildings () {
if( this.searchtext == '' )
return this.buildings;
const re = new RegExp( this.searchtext, 'i' );
return this.buildings.filter( b => {
// return b.name === this.searchtext;
// return b.name.toLowerCase().indexOf( this.searchtext.toLowerCase() ) > -1;
return re.test(b.name);
});
},
},
...
模板很复杂,但像这样:
// the main component
<div id="app">
<GoogleMapPolygon v-for="b in filteredBuildings"
:key="b.id"
:id="b.id"
:name="name"
...
/>
</div>
// the GoogleMapPolygon component
// (no <template>)
...
data: {
polygon: null,
...
},
mounted () {
this.polygon = new google.maps.Polygon({
map: map,
...
});
...
},
destroyed () {
this.polygon.setMap(null);
},
render () {
return false;
},
如果我取消注释该行===
匹配,它就可以正常工作。如果我使用indexOf
匹配或RegExp .test()
,则会出现以下错误:
[Vue 警告]:nextTick 中的错误:"NotFoundError:无法在'节点'上执行'insertBefore':要插入新节点的节点不是此节点的子节点。
并且该应用程序完全死亡。
RegExp
或indexOf
花费的额外时间似乎足以导致问题。这让我想到了nextTick()
,但我不确定我会把它放在哪里。
问题来自于太快地修改建筑物数组(v-for
指令中使用的元素(。从错误来看,Vue 使用这些元素作为参考点来插入其他数组项,但是当 vue 尝试插入新元素时,引用 DOM 元素已经消失了。
这可能只是 Vue 与 Google 地图交互的问题
。解决方案是将正在迭代的组件包装在一个元素中,该元素在切换其他部分时不会消失。例如(来自我最初的问题代码(:
<div id="app">
<section>
<GoogleMapPolygon v-for="b in filteredBuildings"
:key="b.id"
:id="b.id"
:name="name"
...
/>
</section>
</div>
在删除一个标记并将其替换为另一个标记时,我也遇到了这个问题,这也解决了这个问题:
<section>
<GoogleMapMarker
v-if="this.zoom > 15"
:key="'you-are-here-marker'"
:lat="currentLat"
:lng="currentLng"
/>
</section>
<section>
<GoogleMapMarker
v-if="this.zoom < 16"
:key="'campus-center-marker'"
:lat="campusCenter.lat"
:lng="campusCenter.lng"
/>
</section>
在添加部分标签之前,当这两个组件尝试在更改时销毁和创建时this.zoom
我遇到了相同的错误。