Home > Enterprise >  Vue.js: how to access injected value in computed method?
Vue.js: how to access injected value in computed method?

Time:05-16

I used provide/inject mechanism to pass data from parent to grand-children, but in one of my components I need to handle the data before sending it to the template.

So I have:

export default defineComponent({
  name: 'MrComponent',
  inject: ["mydata"],
  computed: {
    processedData() {
      const mydata = this.mydata;
      return mydata   1; // Some handling of the data here
    }
  }
})

But I get the following error:

[vue-cli-service] TS2339: Property 'mydata' does not exist on type 'CreateComponentPublicInstance<{ [x: string & `on${string}`]: ((...args: any[]) => any) | undefined; } | { [x: string & `on${string}`]: ((...args: never) => any) | undefined; }, { chartOptions: { responsive: boolean; maintainAspectRatio: boolean; cutout: string; borderWidth: number; }; }, ... 15 more ..., {}>'.
[vue-cli-service]   Property 'mydata' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: { [x: string & `on${string}`]: ((...args: any[]) => any) | undefined; } | { [x: string & `on${string}`]: ((...args: never) => any) | undefined; }; ... 10 more ...; $watch(source: string | Function, cb: Function, options?: WatchOptions<...> | undefined): WatchStopHan...'.
[vue-cli-service]     41 |   computed: {
[vue-cli-service]     42 |     chartData() {
[vue-cli-service]   > 43 |       const mydata = this.mydata;
[vue-cli-service]        |                           ^^^^^^^^
[vue-cli-service]     44 |     }
[vue-cli-service]     45 |   }
[vue-cli-service]     46 | })

If I access mydata in the template, it works:

<template>
{{ mydata }}
</template>

But I need to do some other operatios with mydata before displaying it. What is the right way to do it?

Thanks.

CodePudding user response:

Are you looking for Utility Types - ComponentCustomProperties?

declare module 'vue' {
  interface ComponentCustomProperties  {
    fastdata: {
      user: {
        nome: string,
        tel: string,
        pts: number,
        nivel: number,
        proximo_nivel: number,
        tot_kg: number,
        coleta: Array<any>,
      },
      noticias: Array<any>,
    },
  }
}

CodePudding user response:

This seems like a Vue bug to me, as the prop should be detected automatically from the inject option, but there are a couple workarounds...

Option 1: Fake prop type in defineComponent

If your component has no props, you could "fake" a mydata prop by specifying it in the first type argument of defineComponent():

export default defineComponent<{ mydata: number }>({
  inject: ['mydata'],
  computed: {
    processedData() {
      // `this.mydata` is number
    }
  }
})

However, this workaround is fragile as it breaks the types as soon as you add the props option.

Option 2: Use Composition API

Switch the relevant parts of the code to the Composition API (i.e., inject() and computed()):

import { defineComponent, inject, computed } from 'vue'

export default defineComponent({
  setup() {
    const mydata = inject('mydata') as number
    const processedData = computed(() => {
      return mydata   1
    })

    return {
      processedData
    }
  }
})
  • Related