skip to Main Content

I have 3 components: Form, Card and Button.

First, my Button.vue component:

<template>
  <div>
    <slot v-bind="{ text }">
      <button>{{ text }}</button>
    </slot>
  </div>
</template>

<script setup>
const props = defineProps({
  text: {
    type: String,
    required: true
  }
});
</script>

Here is my Card.vue component:

<template>
  <Button text="{ text }">
    <template #default="{ text }">
      <button>{{ text }}</button>
    </template>
  </Button>
</template>

<script setup>
import Button from './Button.vue'

const props = defineProps({
  text: {
    type: String,
    required: true
  }
});
</script>

And last, here is my Form.vue component:

<template>
  <div>
    <Card text="Some text">
      <template #default="{ text }">
      </template>
    </Card>
  </div>
</template>

<script setup>
import Card from './Card.vue'
</script>

My question is, how could I pass the text from the Form.vue to the Button.vue child component?

2

Answers


  1. Your code would actually be correct. However, if you want to pass a variable to the component in an HTML attribute, instead of using text=, you should use :text=.

    And instead of passing the { } object, both the Card.vue and Button.vue props expect a String. So, instead of an object, pass the specific string as follows: :text="myVariableWithStringValue"

    Card.vue

    <template>
      <Button :text="buttonText"> <!-- here need use ":text" instead of "text" -->
        <template #default="{ text }">
          <button>{{ text }}</button>
        </template>
      </Button>
    </template>
    
    <script setup>
    import Button from './Button.vue'
    
    const props = defineProps({
      // I renamed your prop from 'props.text' to 'props.buttonText' so that we don't get confused by calling everything 'text'
      buttonText: {
        type: String,
        required: true
      }
    });
    </script>
    

    Form.vue

    <template>
      <div>
        <!-- I renamed your prop from 'props.text' to 'props.buttonText' so that we don't get confused by calling everything 'text' --> 
        <!-- If you want give text from variable then can use :buttonText="variableName" -->
        <!-- Now, just give to "Some text" string as buttonText -->
        <Card buttonText="Some text"></Card>
        <!-- And you can't use <template> in <Card> because don't have got defined <slot> in Card.vue's template -->
      </div>
    </template>
    
    <script setup>
    import Card from './Card.vue'
    </script>
    
    Login or Signup to reply.
  2. Vue3 SFC Playground

    Seems you are overusing component and slot props, you could use just named slots:

    App.vue

    <template>
      <div>
        <Card>
          <template #title>Card title</template>
          Some card content
          <template #button>Some button text</template>
        </Card>
      </div>
    </template>
    
    <script setup>
    import Card from './Card.vue'
    
    </script>
    

    Card.vue:

    <template>
        <h2><slot name="title"></slot></h2>
        <p>
        <slot></slot>
        </p>
        <Button>
            <slot name="button"></slot>
        </Button>
    </template>
    
    <script setup>
    import Button from './Button.vue'
    </script>
    

    Button.vue:

    <template>
        <div>
          <button><slot></slot></button>
        </div>
    </template>
    
    <script setup>
    </script>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search