suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Lösen Sie das Problem nicht vorhandener Eigenschaften von Typen in Vue3 Typescript

Ich versuche, eine Komponente mit Hinweisen von einer API zu füllen. Ich habe eine LeadService-Datei zusammen mit meiner Vue-Vorlagendatei. Das Problem, das ich habe, ist, dass ich einen asynchronen Aufruf für die Vorlagendatei verwende, der funktioniert, aber wenn ich den Wert berechne, wird ein property does not exit on type-Fehler ausgegeben. Es funktioniert tatsächlich und Sie können die richtige Komponente hinter der Fehlermeldung erkennen. Ich weiß nicht, wie ich den Fehler beheben kann.

Dies ist die ServicekategorieLeadService.ts

import ApiService from "@/core/services/ApiService";

interface Lead {
  id: string;
  first_name: string;
  last_name: string;
  lead_form_name: string;
  email: string;
  campaign: string;
  timestamp: number;
  mobile_number: string;
  message: string;
  medium: string;
  city: string;
  state: string;
  leadType: string;
  quality: string;
  source: string;
  call_link: string;
  company: string;
  country: string;
}

export default class LeadService {

  getLeads() {

    const accountInfo = JSON.parse(localStorage.getItem('accountInfo') || '{}');

    ApiService.setHeader();

    return ApiService.query("/leads", {params: {client_id : accountInfo.client_id}})
      .then(({ data }) => {
        let leadData: Lead[] = data['Items'];
        return leadData;
      })
      .catch(({ response }) => {
        return response;
      });

  }
}

Dies ist meine Vue-Vorlage Leads.vue

<template>
  <!--begin::Leads-->
  <div class="row gy-5 g-xl-8 mb-8">
    <div class="col-xxl-12">
      <LeadTracker
        :lead-data="leadData"
        :updateQuality="updateQuality"
        :key="componentKey"
      />
    </div>
  </div>

  <div class="row gy-5 gx-xl-8 mb-8">
    <div class="col-xxl-8">
      <LeadMethods
        chart-height="500"
        :method-data="getLeadMethods"
      ></LeadMethods>
    </div>
  </div>
  <!--end::Leads-->
</template>

<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { setCurrentPageTitle } from "@/core/helpers/breadcrumb";
import LeadMethods from "@/components/leads/methods/LeadMethods.vue";
import LeadTracker from "@/components/leads/tracker/LeadTracker.vue";
import LeadService from "@/core/services/LeadService";
import ApiService from "@/core/services/ApiService";

export default defineComponent({
  name: "leads",
  components: {
    LeadMethods,
    LeadTracker,
  },
  data() {
    return {
      leadData: {},
    }
  },
  beforeMount: async function() {
    this.leadData = await new LeadService().getLeads()
  },
  setup() {
    onMounted(() => {
      setCurrentPageTitle("Lead Activity");
    });

    const sourceThreshold = 5;

    return {
      sourceThreshold,
      componentKey: 0
    };
  },
  computed: {
    getLeadMethods(): object {
      const leadMethods: Array<object> = [];
      const totalLeads = this.leadData.length;

      console.log('called getLeadMethods check this.leadData', this.leadData);

      // Get the total number of Paid Media leads
      const totalPaid = this.leadData.filter(
        lead => lead.medium == "paid_media"
      ).length;

      // Get the total number of Calls
      const totalCall = this.leadData.filter(lead => lead.leadType == "call")
        .length;

      // Separate form leads from the rest
      const formData = this.leadData.filter(lead => lead.leadType == "form");

      // Make array for form names
      const formTypes: Array<string> = [];
      this.leadData.filter(lead => {
        if (!formTypes.includes(lead.lead_form_name))
          formTypes.push(lead.lead_form_name);
      });

      // Create objects for each form by name, push to leadMethods
      formTypes.filter(type => {
        let totalFormLeads = 1;
        formData.filter(form => {
          if (form.lead_form_name == type) totalFormLeads++;
        });
        const formMethod = {
          name: type,
          description: "Lorem ipsum dolor sit amet, consectetur.",
          total: totalFormLeads,
          percent: Math.round((totalFormLeads / totalLeads) * 100)
        };
        leadMethods.push(formMethod);
      });

      const callTracking = {
        name: "Location Based Call-Tracking",
        description: "Lorem ipsum dolor sit amet, consectetur.",
        total: totalCall,
        percent: Math.round((totalCall / totalLeads) * 100)
      };
      const paidSearch = {
        name: "Paid Search",
        description: "Lorem ipsum dolor sit amet, consectetur.",
        total: totalPaid,
        percent: Math.round((totalPaid / totalLeads) * 100)
      };

      leadMethods.push(callTracking, paidSearch);

      return leadMethods;
    }
  }
});
</script>

Das Problem beginnt mit meiner Berechnungsfunktion, ich beginne zu filtern this.LeadData Grundsätzlich löst jeder Filter Property does not exit on type Fehler aus, aber es gibt sie.

Es ist wichtig zu beachten, dass es sich bei der Einstellung this.leadData um einen Proxy handelt. Für jede Hilfe wäre ich sehr dankbar. Ich würde gerne wissen, ob es möglich ist, den Fehler zu unterdrücken, auch wenn mir diese Lösung nicht gefällt.

Zum Beispiel im ersten Filter in der Berechnungsmethode

// Get the total number of Paid Media leads
      const totalPaid = this.leadData.filter(
        lead => lead.medium == "paid_media"
      ).length;

medium ist eine Eigenschaft von leadData und ich kann es tatsächlich auf der Konsole protokollieren und es funktioniert gut, aber es löst immer noch mediumleadData 的一个属性,我实际上可以控制台记录它并且它工作得很好,但它仍然总是抛出 property does not exit on type aus.

P粉336536706P粉336536706247 Tage vor768

Antworte allen(1)Ich werde antworten

  • P粉111627787

    P粉1116277872024-03-26 11:33:46

    leadData 的类型是从 data() 中的声明推断出来的。它被初始化为 {},这意味着它的类型是一个不可变的空对象(并且不能附加任何属性)。但是,leadData 最终被分配了 LeadService().getLeads() 的返回值,所以它的类型实际上应该是 Lead 对象的数组。

    要正确输入 leadData,请使用 Lead[] 的类型断言:

    export default defineComponent({
      data() {
        return {
          //leadData: {}, ❌
          leadData: [] as Lead[], ✅
        }
      }
    })
    

    Antwort
    0
  • StornierenAntwort