vuejs3

How to pass prop to child component in vue 3


I have defined properties in the parent component which are then passed externally to the parent component, how can I use these properties in the child component.

Parent.vue

<script setup>

defineProps({
  col: { type: Number, default: 3 },
  // default | auto | mid | large | large2x
  labelWidth: { type: String, default: 'default' },
})
</script>

<template>
<div>
  <slot></slot>
</div>
</template>

Child.vue

<script setup>
</script>

<template>
  <!-- How to use labelWidth from parent component here -->
  <div>
    <label>Hello</label>
    <slot></slot>
  </div>
</template>

App.vue

<script setup>
import Parent from 'Parent.vue'
import Child from 'Child.vue'
</script>

<template>
<Parent label-width="large">
  <Child></Child>
  <Child></Child>
</Parent>
</template>

Solution

  • You can use a render function to add extra props to the Parent's default slot (I've passed all Parent's props, you can customize).

    You can check what props are supported by child components and pass only though props to avoid fallback attributes.

    Playground

    Parent.vue

    <script setup>
    
    import {useSlots, h} from 'vue';
    
    const props = defineProps({
      col: { type: Number, default: 3 },
      // default | auto | mid | large | large2x
      labelWidth: { type: String, default: 'default' },
    })
    
    const $slots = useSlots();
    
    const slotted = () => $slots.default().map(vnode => {
      const filtered = (vnode.type.props ?? []).reduce((r, key) => (r[key] = props[key], r), {});
      return h(vnode, filtered);
    });
    
    </script>
    
    <template>
    <div>
      <slotted/>
    </div>
    </template>
    

    Child.vue

    <script setup>
    defineProps(['labelWidth']);
    </script>
    
    <template>
      <!-- How to use labelWidth from parent component here -->
      <div>
        <label>Hello (labelWidth: {{labelWidth}})</label>
        <slot></slot>
      </div>
    </template>