【问题标题】:Variable undefined unless wrapped in setTimeout变量未定义,除非包含在 setTimeout 中
【发布时间】:2021-07-25 23:10:41
【问题描述】:

我有一个空表单,我想在已安装的生命周期挂钩中为活动用户设置“负责职员”输入。它看起来像这样:

<b-form-select
     v-model="form.responsible_clerk"
     :options="clerks"
     required
></b-form-select>
data() {
     return {
          form: {
               responsible_clerk: ""
          }
     }
},
computed: {
      user() {
           return this.$store.getters.getUser;
      }
},
mounted() {
     this.form.responsible_clerk = this.user.name + " " + this.user.lastname;
}

这对于 this.form.responsible_clerkthis.user 都显示为 undefined。

当我用 0ms 超时将挂载的钩子的内容包装在 setTimeout 中时,它会按预期工作。

mounted() {
     setTimeout(() => {
          this.form.responsible_clerk = this.user.name + " " + this.user.lastname;
     },0)
}

我还需要在其他几种情况下执行此操作,其中我覆盖了挂载钩子中的变量。 (例如,当使用 vue bootstrap 的 b-collapse 并在挂载时将所有折叠元素设置为 true 并在以管理员身份创建用户时自动设置用户的公司时,也在挂载时)

有人可以向我解释为什么会发生这种情况,以及如何防止反复使用 setTimeout。这对我来说没有意义,Vue 不应该这样工作。

编辑: getUser 是一个 vuex getter:

getUser(state) {
     return state.user;
}

编辑 2: 刚刚踏入它,又在做其他事情:

computed: {
    max() {
        return document.getElementById("collapse-header")
            .querySelectorAll('div')
            .length;
    }
}

这不起作用,用 setTimeout 包装它会...

【问题讨论】:

  • getUser getter 会发生什么?你在那里发出异步请求吗?
  • getUser 是一个 vuex getter:getUser(state) { return state.user; }
  • 如果它为空,我会收到控制台警告,并且变量会在收到其值时动态更改,我不介意。但它根本不起作用。 this.form.responsible_clerk = this.user?.name + " " + this.user?.lastname; 也没有为我做任何事情。如果变量为 null 只是稍后动态更改,则不会有问题,但它可能不会动态调整变量的值。它只适用于 setTimeout。
  • 你确定它实际上是undefined,而不是""
  • 如果 state.use 最初为 NULL,然后收到一个值 - 您的 responsible_clerk 不会注意到这一点,除非您创建一个观察者并在每次 state.user 更改时更新 responsible_clerk

标签: javascript vue.js vuex bootstrap-vue


【解决方案1】:

只有你的user 是一个计算属性,你只是调用连接mounted 中的用户名和姓氏。当mounted 运行后,它就不再被调用。因此,当您设置超时时它会起作用,然后用户就有时间从商店中获取并可以显示。您可以使用watch 来监听user 的变化,然后设置值。由于您的表单是一个对象,我们需要收听deep,也许您还需要使用immediate。所以添加一个观察者:

watch: {
    user: {
        immediate:true,
        deep: true,
        handler(user) {
            this.$set(this.form, 'responsible_clerk', user.name + " " + user.lastname);
        }
    }
}

【讨论】:

  • 我了解您的解决方案。我经常遇到像这样的情况。大多数时候它的东西只需要发生一次。就像从商店中获取用户名或“isCollapsed”数组一样。我宁愿只写一次 setTimeout 0 而不是为每一种情况写一个观察者。我不能是唯一一个,对于这种情况不应该有像“afterMounted”生命周期钩子之类的东西,我觉得使用 setTimeout 是一种不好的方法,但比编写观察者更节省时间。观察者适用于多次更改的变量...
猜你喜欢
  • 1970-01-01
  • 2012-10-09
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
  • 2012-09-13
  • 2012-04-18
  • 2015-08-29
相关资源
最近更新 更多