Vue.js的refs是未定义的,尽管.$refs显示它们在那里,

2lpgd968  于 2023-06-24  发布在  Vue.js
关注(0)|答案(8)|浏览(115)

我有一个组件的参考资料

<Gmap ref="mapRef">

在装裱的时候我是这样做的,看对象是否可用

mounted(){
    let self = this
    console.log(self.$refs) // Shows the mapRef object reference
    console.log(self.$refs.mapRef) // returns undefined ???
}

self.$refs显示...

mapRef: VueComponent {_uid: 207, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

为什么self.$refs.mapRef返回undefined??即使它就在那里??

sycxhyv7

sycxhyv71#

我使用v-show而不是v-if解决了这个问题。
我把组件放在了一个v-if语句中。

<div v-if="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

我刚把那个改成了v-show

<div v-show="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

现在该对象在mounted()中可用。仍然觉得奇怪的是console.log(this.$refs)显示它作为this.$refs上的一个键可用,即使它实际上不是?这是奇怪的行为。
另一个奇怪的事情是,即使我试图在我的数据加载部分访问这个.$refs.mapRef,在数据加载之后,(即isLoading = false之后),我仍然无法访问它。即使那样,它也应该是可用的,因为V-如果通过了。
所以v-show解决了这个问题,只是隐藏了div,而不是不渲染它。愚蠢的小工作。

zengzsys

zengzsys2#

我在获取传单Map示例的引用时遇到了类似的问题,尝试等待“nextTick”

mounted(){
  this.$nextTick(()=>{
    let self = this
    console.log(self.$refs) // Shows the mapRef object reference
    console.log(self.$refs.mapRef) // returns undefined ???
  });
}

请参阅文档了解更多信息-https://v2.vuejs.org/v2/api/#vm-nextTick和https://v2.vuejs.org/v2/api/#mounted

xghobddn

xghobddn3#

主要的解决方案是确保组件不是动态导入的
您仍然需要避免用v-if Package 组件,并在mounted()中使用this.$refs.mapRef,而不是created()
我没有使用Vue Google Maps插件/组件,而是使用了我自己的自定义组件

方法一

用途:

import CustomComponent from './CustomComponent ';

export default {
  components: {
    CustomComponent,
  },
  ...
}

而不是

export default {
  components: {
    CustomComponent: () => import('./CustomComponent'),
  },
  ...
}

方法二

mounted()中使用this.$refs.mapRef,而不是created()
这样,就不需要setTimeout()this.$nextTick()
正确方法:

mounted(){
  //works! child components were loaded
  console.log(this.$refs.mapRef) 
}

错误方式:

created(){
  //DON'T DO THIS! child components hasn't loaded
  console.log(this.$refs.mapRef) 

  //might work but it's an unreliable workaround
  setTimeout(()=>{
    console.log(this.$refs.mapRef)
  }, 0);

  //might work but it's an unreliable workaround
  this.$nextTick(()=>{
    console.log(this.$refs.mapRef)
  });

}

方法三

不要使用v-if Package 子组件,而使用v-show
正确方法:

<div v-show="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

错误方式:

<div v-if="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

其他方法(不正确,不是解决方案)

下面是我尝试过的方法,但直到我使用了上面的方法(停止使用动态导入)才能工作。
我已经把this.$refs.mapRef放在mounted()中试着用setTimeout()和2层this.$nextTick()包裹它。
它只在热重载时工作,但在页面刷新后不再工作

mounted(){
  setTimeout(()=>{
    this.$nextTick(()=>{
      this.$nextTick(()=>{
        console.log(this.$refs.mapRef) // returns undefined
      });
    });
  }, 0);
}

感谢另一个答案中的这条评论:如何从vue.js中的父方法访问子方法

3qpi33ja

3qpi33ja4#

你可以用vue2-google-maps提供的$mapPromise方法 Package 你的函数,这将确保Map在运行你的代码之前已经完全呈现:

let self = this;
self.$refs.mapRef.$mapPromise.then(() => {
    console.log(self.$refs.mapRef);
})

这应该可以解决代码依赖GoogleMap来运行的任何问题。

  • 注意:$mapPromise在过去的版本中被命名为$mapCreated

参见文档:https://github.com/Jeson-gk/vue2-google-maps/blob/master/API.md#mapcreated--promisegooglemapsmap

console.log(self.$refs);显示值的原因是self.$refs是通过引用传递的。因此,当您查看控制台时,其余数据在几毫秒内完成加载。并且self.$ref.mapRef不是通过引用传递的,所以它仍然是undefined,就像在运行时一样。
尝试直接在console.log(self.$refs);之后和console.log(self.$refs.mapRef);之前添加**断点 *,可能会发现数据没有加载。

mccptt67

mccptt675#

在我的例子中,我使用了ref沿着v-for,我错过了ref只在v-for在dom中渲染后才生成的事实,并且我使用了v-for和一个state数组属性,该属性在调用mounted后几秒钟填充,并且我试图在填充state数组之前访问我的ref。

thigvfpy

thigvfpy6#

似乎你在使用:https://github.com/diegoazh/gmap-vue,正如文档所说:https://diegoazh.github.io/gmap-vue/#lazy-loading

async mounted() {
    await this.$gmapApiPromiseLazy()

    ...
}

这工作完美。

lyr7nygr

lyr7nygr7#

你可以在组件中添加eager prop,因为vuetify 2中的延迟加载。

xzv2uavs

xzv2uavs8#

您可以按如下方式使用它,尽管我不知道它是否会破坏商业项目的typescript实现。

(this as any).$refs.mapRef

相关问题