JS_is_awesome18
JS_is_awesome18

Reputation: 1757

How to use Provide/Inject to pass an array from a parent component to a grandchild component

I am attempting to use Provide/Inject functionality to enable a parent component to "provide" an array to a grandchild component, based on the following Vue 3 Composition API docs: https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity

The array in my parent component looks like this:

const arrayItems= [
  { name: 'itemOne' },
  { name: 'itemTwo' },
  { name: 'itemThree' },
  { name: 'itemFour' },
  { name: 'itemFive' },
]

The above documentation for Provide/Inject appears to only show examples of providing primitive types. Based on the concepts in the docs, I attempted to provide an array to a grandchild component, but the injected array doesn't appear to be rendering on the grandchild. Any idea how to set up Provide/Inject in order to pass the array to the grandchild component?

Here is my code so far:

Parent

<template>
  <div class="h-full">
    <child />
  </div>
</template>

<script>
import { provide } from 'vue'
import { Child } from '@Child'

const arrayItems= [
  { name: 'itemOne' },
  { name: 'itemTwo' },
  { name: 'itemThree' },
  { name: 'itemFour' },
  { name: 'itemFive' },
]

export default {
  components: {
    Child
  },
  setup() {
    provide('navigation', arrayItems)

    return {
      arrayItems
    }
  }
}
</script>

Child

<template>
  <div>
    <grandchild />
  </div>
</template>

<script>
import { GrandChild } from '@'
export default {
    components: {
        GrandChild 
    }
}
</script>

GrandChild

<template>
  <div>
     <ul>
       <li v-for="item in items" :key="item.id"></li>
     </ul>
  </div>
</template>

<script>
import { inject } from 'vue'
export default {
    setup() {
        const { items } = inject('navigation')

        return {
            items
        }
    }
}
</script>

Upvotes: 0

Views: 2026

Answers (1)

tony19
tony19

Reputation: 138316

In GrandChild.vue, you're destructuring the inject-ed value for an items property, but the provide-ed item is an Array, which has no such property.

Solution

Don't destructure the inject-ed value:

// GrandChild.vue
export default {
  setup() {
    // const { items } = inject('navigation') ❌
    const items = inject('navigation') ✅
    ⋮
  },
}

demo 1

Or provide the array data in an object with an items property:

// Parent.vue
export default {
  setup() {
    // provide('navigation', arrayItems) ❌
    provide('navigation', { items: arrayItems }) ✅
    ⋮
  }
}

demo 2

Upvotes: 4

Related Questions