Passing value from parent to child using slot probably

Viewed 65

I probably don't understand how it should be done. I spent a few hours to achieve this functionality but with no luck. Here is what I have:

Child

<template>
  <div>
    Data from dialog: {{aaa}}
  </div>
</template>

<script>
export default {
  name: 'frm',
  props: [
    'aaa'
  ]
}
</script>

Parent:

<template>
  <div>
    <slot :aaa="some"></slot>
  </div>
</template>

<script>
export default {
  name: 'dlg',
  data: () => ({
    some: 'data from dialog'
  })
}
</script>

View:

<template>
  <div>
    <dlg>
      <frm></frm>
    </dlg>
  </div>
</template>

<script>
import Dialog from '@/components/dialog.vue'
import Frm from '@/components/frm.vue'

export default {
  name: "View",
  components: {
    'dlg': Dialog,
    'frm': Frm
  }
};
</script>

Edit: Real code

dialog-template:

    <template>
      <v-dialog
        v-model="internal.dialogOpened"
      >
        <!-- ... -->
        <slot :aaa="'dsada'"></slot>
      </v-dialog>
    </template>

details-task-dialog:

<template>
  <dlg-template large position='right' :onclose="close" :load="loadRetry">
    <task-details-form /> <!-- just regular component in which I want to get value passed through slot in dialog-template -->
  </dlg-template>
</template>
<script>
import DlgTemplate from '@/components/site/dialogs/dialog-template.vue'
export default {
// ...
  components: {
    'dlg-template': DlgTemplate,
    'task-details-form': DetailsForm,
  },

I want to avoid passing prop in View but I don't know how :/ I've read about 'slot-scope' unfortunately with no success. How to achieve such functionality?

1 Answers

Edit: real code

Based on your real world code, you were only missing the attachment of the scope, see below.

dialog-template:

    <template>
      <v-dialog v-model="internal.dialogOpened">
        <!-- ... -->
        <slot :aaa="'dsada'"></slot>
      </v-dialog>
    </template>

details-task-dialog:

<template>
  <dlg-template large position='right' :onclose="close" :load="loadRetry">
    <task-details-form v-slot="{ aaa }"> 
      <!-- you can use the var `aaa` here  -->
    </task-details-form>
  </dlg-template>
</template>

I'd still wager if you want to use aaa inside task-details-form component you have to pass it down as a prop. But it looks wierd to me, because I'm unsure of the execution order right now (v-slot vs v-bind), but try it like this:

<template>
  <dlg-template large position='right' :onclose="close" :load="loadRetry">
    <task-details-form v-slot="{ aaa }" :your-a-prop-name="aaa" />
  </dlg-template>
</template>

Edit 2: after testing

v-bind shorthand is not working on <slot>:

dialog-template:

    <template>
      <v-dialog v-model="internal.dialogOpened">
        <!-- ... -->
        <slot v-bind:aaa="'dsada'"></slot>
      </v-dialog>
    </template>

details-task-dialog:

<template>
  <dlg-template large position='right' :onclose="close" :load="loadRetry">
    <template v-slot="{ aaa }"> <!-- has to preceed v-bind -->
    <task-details-form :propertyOnComponent="aaa" /> <!-- now you cand bind it --> 
    </template>
  </dlg-template>
</template>

Original:

I think you misunderstood slots. Check the docs:

That slot has access to the same instance properties (i.e. the same “scope”) as the rest of the template. The slot does not have access to child’s scope.

Slots

So you could do that, but then your code becomes:

  <template>
  <div>
    <dlg>
      <frm>
        <child :aaa=“dialogData” />
      </frm>
    </dlg>
  </div>
</template>

Frm:

<template>
  <div>
    From component
    <slot></slot>
  </div>
</template>

If you would define a slot on frm as you are suggesting, you would be able to fill that slot with a specific template and you can receive(!) the scope for that slot.

The deprecated slot-scope which you mentioned would provide you with a bound context from the child to be exposed in your overriding slot in the parent, that’s the opposite of what you want.

Just out of curiosity, why not send down the dialog data to the form as a property? That’s exactly what it’s for.

Related