我有一个<div id="map" />

我有一个初始化地图的安装方法。

mounted(){
 this.map = L.map(this.mapId, { preferCanvas: true }).setView(
  [this.initialLatitudeOriginalPoint, this.intiialLongitudeOriginalPoint],
        3
 )
L.tileLayer(
        tileconfig + '?access_token=' + key
        { maxZoom: 25, id: 'mapbox.streets' }
      ).addTo(this.map)
}


我有一个叫做标记的道具。我有一个观察者,马上就可以了

markers:{
      handler(newVal, oldVal){
        this.showMarkers()
      },
      immediate: true
    },


问题-好像先被调用watcher。安装之前。然后showMarkers函数将引发错误,因为将不会定义映射,因为watcher首先出现在mounted之前。我真的需要那个观察员立即采取行动。我有什么办法可以知道,在未定义map之前,观察者应该等待吗?

我的想法:我想到使用nextTick。但我对此一无所知。如果我在观察者的处理函数中编写this。$ nextTick,那么何时调用nextTick回调? dom在此特定组件或什至是父母的父母中更新之后?如果它不在乎当前组件,那么在我的情况下,nextTick可能有点错误。我只想了解有关nextTick的最后一件事。有什么线索吗?

最佳答案

首先,您正确地认为immediate将导致在安装组件之前触发watchwatch的作用主要是根据其他属性执行对属性的更新。因此它将等待所有基本属性(属性,数据等)被初始化,但是它假定渲染需要watch的输出才能正确渲染。在您的情况下,这是不正确的。

我写这个的方式是:

mounted () {
  // ... map stuff ...

  this.showMarkers()
},

watch: {
  markers: 'showMarkers'
}


如果其中需要一个nextTick,我倾向于在showMarkers内执行该操作,而不是使其成为调用方的问题。

但是,您不必这样做。您可以按照问题中的建议使用immediatenextTick进行操作。

因此,关键是要了解何时精确调用nextTick

如果渲染依赖关系发生变化,Vue将不会立即重新渲染组件。而是将其添加到队列中。一旦所有其他代码完成运行,Vue将处理该队列。这比听起来更复杂,因为父/子层次结构中的各个组件可能需要更新。更新父母可能会导致孩子不再存在。

处理完队列并更新DOM后,Vue将调用任何nextTick回调。回调内部发生的任何进一步更改将添加到新的渲染队列中。

这里有几个要注意的要点。


尽管Vue可能已经更新了DOM,但在JavaScript代码完成之前,浏览器实际上不会绘制所有新节点。这包括任何nextTick回调。因此,如果nextTick触发进一步的更新,则用户将看不到页面的临时状态。
所有这些都假设Vue正在跟踪更新并执行渲染。如果您要在Vue之外进行渲染,就像通过Leaflet进行渲染一样,那么Vue不能提供太多帮助。


因此,请考虑以下内容:

markers:{
  async handler(newVal, oldVal){
    await this.$nextTick()
    this.showMarkers()
  },
  immediate: true
},


我在这里使用async / await而不是传递回调,但是最终结果是相同的。

第一次调用handler时,它是在呈现组件之前。所有渲染完成(包括其他组件)后,将调用$nextTick。只要其他组件不假定标记已经存在,这应该不成问题,它们仍将在用户看到任何东西之前创建。

markers随后更改时,它实际上可能不会触发Vue中的任何渲染。除非您在模板之一中的某处使用markers,否则它不会成为渲染依赖项,因此不会触发新的渲染。这不一定是问题,因为即使没有任何Vue呈现,$nextTick仍然可以工作。

关于javascript - vue nexttick map ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58707381/

10-12 04:59