javascript - VueJS v-if with 方法总是返回 false

标签 javascript vue.js vuejs2

我正在使用 v-for 循环遍历我的消息。现在,我想要的是检查每条消息的日期,如果日期不同,则显示日期,将其添加到我的数据中,然后继续。这意味着每一天都应该只显示一次。

<template v-for="(message, index) in messages">
  <div class="spacer">
    <span class="grouped-date" v-if="displayPostDate(message.created_at)">
        {{ message.created_at }}
    </span>
  </div>
</template>

奇怪的是,在我的方法 displayPostDate() 中,我可以检查:

if (!this.datesDone.includes(d)) {}

当我 console.log 它时,它成功运行,但无论我返回什么,Vue 都不会解析正确的数据。

这是displayPostDate():

let d = date.substring(0, 10);

if (!this.datesDone.includes(d)) {

    console.log('not present');
    this.datesDone.push(date.substring(0, 10));

    return true;

} else {

    console.log('present');
    return false;

}

最佳答案

这就是正在发生的事情......

displayPostDate 方法具有更新 react 依赖项的副作用(即,它更新 datesDone[]),这会导致另一个渲染周期,从而调用该方法再次。

例如,假设您有一个空的 datesDone[]messages[] 中的四个项目,每个项目都有唯一的 created_at 日期。

  1. 在初始呈现时,displayPostDate 在其 datesDone[] 中找不到任何 created_at 日期,因此它将它们附加到数组中。它还返回 true 以显示 span
  2. Vue 检测到 datesDone[] 的变化——displayPostDate 的依赖项,因此它开始另一个渲染周期。
  3. 在第二次呈现时,displayPostDate 找到 datesDone[] 中的所有日期,因此 datesDone[] 没有发生任何变化。它还返回 false 以隐藏 span。由于没有更改依赖项,Vue 不会重新渲染。

这是解决方法...

首先,注意在模板中调用一个方法是inefficient因为每次渲染模板时都会调用它,这可能会发生多次,这反过来又要求该方法是幂等的(并且不更改其 react 性依赖项)以避免渲染循环。

为了解决这个问题,一个更简单的解决方案是预过滤列表,这样它只包含您想要显示的项目(而不是在模板中有条件地呈现)。这有一个额外的好处,可以简化您的模板并消除对 datesDone[] 的需要,假设它除了跟踪重复项没有其他用途。我建议将此列表创建为 computed property这样结果就会被缓存,而不是在另一个渲染周期中不必要地重新计算:

// script
computed: {
  uniqueMessages() {
    const uniq = this.messages.reduce((c, msg) => {
      c[msg.created_at] = c[msg.created_at] || msg
      return c
    }, {})

    return Object.values(uniq)
  }
}

// template
<div v-for="message in uniqueMessages">
  <span class="grouped-date">
    {{ message.created_at }}
  </span>
</div>

demo

关于javascript - VueJS v-if with 方法总是返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55344095/

相关文章:

javascript - .vue 组件中的条件样式表

javascript - 删除 v-on :click event from an element when it's clicked on

javascript - 在 Firefox 插件中注册控制台服务监听器

javascript - 如何在选中/取消选中复选框时切换(打开/关闭)行为?

javascript - 如何将用户输入与数组内的值进行比较?

vue.js - Electron Ipc渲染向Vuex发出事件

javascript - vue loader 一个扩展的不同加载器

vue.js - Vuetify 在 css 中自定义 v-btn Prop

javascript - 在同一行中分配变量和更改属性

javascript - Vue.js 单击并删除上一个时添加事件类