vue.js - vue v-for av typescript enum


Hvorfor viser denne v-for-løkka over en enum både navnene og verdiene?

Hvordan kan jeg iterere bare over nøklene?

export enum Colors {
  "RED" = 1,
  "BLUE" =  2,
  "GREEN" = 3,
}
<template>
   <div>
      <v-chip v-for="key in Colors" :key="key">{{key}}</v-chip>
   </div>
</template>

<script lang="ts">
import {Colors} from "./Enums"
import Vue from "vue";
export default Vue.extend({
  data: () => ({
     Colors,
  }),
});
</script>

Dette resulterer merkelig nok i 6 brikker, men jeg ville forventet bare 3.

  • RØD
  • BLÅ
  • GRØNN
  • 1
  • 2
  • 3

Svar #1

Fordi v-for lister opp alle egenskaper til et objekt, vil det vise både fremover- og bakoveregenskapene til Typescript-enum. Du må filtrere nøklene selv, muligens ved å bruke Number.isInteger().

For kontekst, får Typescript-enumerasjoner omvendte kartlegginger som standard:

I tillegg til å opprette et objekt med egenskapsnavn for medlemmer, får også numeriske enum-medlemmer en omvendt kartlegging fra enum-verdier til enum-navn. For eksempel, i dette eksempelet:

enum Enum {
  A,
}

let a = Enum.A;
let nameOfA = Enum[a]; // "A"

TypeScript kompilerer dette ned til følgende JavaScript:

"use strict";
var Enum;
(function (Enum) {
  Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
let a = Enum.A;
let nameOfA = Enum[a]; // "A"

I denne genererte koden blir en enum kompilert til et objekt som lagrer både fremover- (name -> value) og bakover- (value -> name) mappinger. Referanser til andre enum-medlemmer blir alltid skrevet ut som egenskapsaksesser og aldri inline.

Svar #2

Basert på Jeffs svar, vil koden se omtrent slik ut:

<template>
    <div>
      <v-chip 
        v-for="([value, key], idx) in Object.entries(Colors).filter(([_, k]) => Number.isInteger(k))" 
        :key="idx"
      >
        {{ key }}
      </v-chip>
    </div>
</template>

Relaterte artikler