'Vue.js: how to access injected value in computed method?
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.
Solution 1:[1]
This seems like a Vue bug to me, as the prop should be detected automatically from the inject option (filed vuejs/core#5931), 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
}
}
})
Solution 2:[2]
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>,
},
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Fody |
