【问题标题】:Why does my filtered Object.values() return weird data?为什么我过滤的 Object.values() 返回奇怪的数据?
【发布时间】:2021-10-21 02:39:45
【问题描述】:

我写了一个 Vue3 组件,它应该在芯片中显示数据。我向它传递了一个对象,其中键是索引,值的字段之一是要显示的元素。

完整的文档代码如下

<template>
  <div class="row">
    <div>a fixed entry during debug</div>
    <q-chip v-for="alert in failedAlerts" :key="alert.Id" color="orange">{{ alert.FullTargetName }}</q-chip>
  </div>
</template>

<script lang="ts">

import {toRef, Ref, computed, watch} from 'vue'
import log from 'assets/log'

interface Alert {
  IsOK: boolean;
  FullTargetName: string,
  Why: string,
  Extra: string,
  Id: string,
  When: string
}

function alertFactory(): Alert {
  return {
    Extra: '', FullTargetName: 'dummy alert', Id: '0', IsOK: false, When: '0', Why: 'dummy alert explanation',
  }
}

export default {
  name: 'Homemonitor',
  // the complete props definitiin is temporarily commented out to make sure the problem
  // does not come from here
  // props: {
  //   alerts: {
  //     type: Object,
  //     default: () => alertFactory(),
  //   },
  // },
  props: ['alerts'],
  setup(props) {
    // TODO: review the global eslint exclusions below
    /* eslint-disable @typescript-eslint/no-unsafe-call */
    /* eslint-disable @typescript-eslint/no-unsafe-return */
    /* eslint-disable @typescript-eslint/no-unsafe-member-access */

    let failedAlerts = computed(() => Object.values(toRef(props, 'alerts')).filter((x: Alert) => !x.IsOK))

    return {failedAlerts}
  },
}
</script>

<style scoped>

</style>

在 DevTools → Vue 中查看时,我看到 failedAlerts 不是 Alert 的整洁数组,而是

alert 中的 props and setup → failedAlerts → alerts` 有预期的内容

Object.values() 以数组的形式返回对象的值(然后我将其归档)。 我预计failedAlerts 将是一个由alerts 的值组成的数组(已过滤)。

使用上面的数据,几乎就是:(IsOKtrue 所以它会被过滤掉,但想法是这样)

// failedAlerts

[
  {
    "IsOK":true,
    "FullTargetName":"bind → Amazon_Fire",
    "Why":"",
    "Extra":"",
    "Id":"8bd3b2c7fe73ea6c0d0aac324baaa354",
    "When":"2021-08-19T13:02:33+02:00"
  },
(...)
]

为什么failedAlerts 是我的情况?


编辑:在仔细检查了我的代码中的类型混乱之后(主要感谢@EstusFlask 的坚持),我想我想出了&lt;script&gt; 部分的正确代码。

<script lang="ts">

import {computed, Ref, toRef, watch} from 'vue'

interface Alert {
  IsOK: boolean;
  FullTargetName: string,
  Why: string,
  Extra: string,
  Id: string,
  When: string
}

function alertFactory(): Record<string, Alert> {
  return {
    'dummy index':
        {
          Extra: '', FullTargetName: 'dummy alert', Id: '0', IsOK: false, When: '0', Why: 'dummy alert explanation',
        },
  }
}

export default {
  name: 'Homemonitor',
  props: {
    alerts: {
      type: Object,
      required: true,
      // default: () => alertFactory(),
    },
  },
  // props: ['alerts'],
  setup(props) {
    // TODO: review the global eslint exclusions below
    /* eslint-disable @typescript-eslint/no-unsafe-call */
    /* eslint-disable @typescript-eslint/no-unsafe-return */
    /* eslint-disable @typescript-eslint/no-unsafe-member-access */

    let failedAlerts = computed(() => Object.values(props.alerts as Ref<Record<string, Alert>>).filter((x: Alert) => !x.IsOK))

    return {failedAlerts}
  },
}
</script>

【问题讨论】:

  • 它返回它应该返回的内容,即对象值的数组。请澄清您期望 failedAlerts 的样子。
  • @EstusFlask:很抱歉不够清晰。我添加了一个明确的句子和一个符合我预期的示例输出
  • 你通过断言 props.alerts 是一个数组 Ref&lt;Alert[]&gt; 来欺骗 TS,但它是一个对象。而这个alertFactory() 是一个对象,也不是一个数组。
  • @EstusFlask:啊废话,复制/粘贴太多。谢谢!我删除了断言,但问题是一样的。
  • @WoJ 仅供参考,toRef(props, 'alerts') 是不必要的。您可以在计算中使用props.alerts,而不必解开任何引用。

标签: javascript typescript vue.js vuejs3


【解决方案1】:

toRef 返回类型的引用

interface Ref<T> {
  value: T
}

在此调用 Object.values 返回您正在获取的类型的数组。

要获取对象的实际值,需要使用toRef(...).values

由于 props.alert 已经是反应式的,toRef 构造是不必要的(正如其他人所指出的那样)。所以最好使用-Object.values(props.alerts)

【讨论】:

  • toRef(...).value 是无意义的构造。 toRef(props, 'alerts').valueprops.alerts
  • @WoJ,您的编辑删除了对原始问题的解释。我已编辑以包含这两种解决方案。
猜你喜欢
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 2018-02-04
  • 1970-01-01
相关资源
最近更新 更多