this.$refs 或文档在 Mounted() 中不可见,除非我使用 setTimeout [关闭]

2023-12-30

我有一个奇怪的问题。我以为$refs可以从mounted()生命周期

但如果我尝试log直接它是我未定义的对象:

mounted() {
    // logs undefined
    console.log(
      this.$refs.tabsMenu
    ) 
}

等待 1ms 后它就被定义了,我可以得到对象

mounted() {
    setTimeout(() => {
      // logs the object
      console.log(
          this.$refs.tabsMenu
      )
    }, 1) // <-- just 1ms!
}

对此有什么想法吗?

我的(简化的)模板如下所示

<template>
  <div>
    <baseContainer>
      <ul ref="tabsMenu" id="tabs-menu" class="flex-inline flex w-full">
        <li>Home</li>
        <!-- many more items -->
        <li>Contact</li>
      </ul>
     </baseContainer>
  </div>
</div>

那是因为mounted()不保证 DOM 已经完成渲染。您需要等待this.$nextTick():

mounted() {
    this.$nextTick(() => {
        console.log(this.$refs.tabsMenu) 
    });
}

之所以setTimeout(callback, 1)对你有用是因为你本质上将回调(在你的代码中,访问引用并将其记录到控制台)推迟到调用堆栈的末尾,也就是 DOM 完成渲染的时候。

如果您熟悉使用 async/await,也可以这样做:

async mounted() {
    await this.$nextTick();
    console.log(this.$refs.tabsMenu);
}

Update: 看来你的ref元素实际上包含在另一个 VueJS 组件中<baseComponent>。在这种情况下,听this.$nextTick()在父/消耗组件上是不够的,因为它不能保证内部组件已安装and呈现。

如果您仍然需要使用这种方法,那么我唯一的建议是确保内部<baseComponent>当它被安装并且它的 DOM 被渲染时会发出某种事件,例如通过发射ready event:

// Inside baseComponent
mounted() {
    this.$nextTick(() => {
        this.$emit('ready');
    });
}

然后,在您的父组件中,您可以监听该事件,如下所示:

<baseContainer v-on:ready="onReady">
  <ul ref="tabsMenu" id="tabs-menu" class="flex-inline flex w-full">
    <li>Home</li>
    <!-- many more items -->
    <li>Contact</li>
  </ul>
</baseContainer>

然后在组件的代码中:

methods {
    onReady: function() {
        console.log(this.$refs.tabsMenu);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

this.$refs 或文档在 Mounted() 中不可见,除非我使用 setTimeout [关闭] 的相关文章

随机推荐