使用插槽将值从父级传递给子级

时间:2020-06-12 07:46:07

标签: vue.js

我可能不明白该怎么做。我花了几个小时来实现此功能,但是没有运气。这是我所拥有的:

孩子

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

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

父母:

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

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

查看:

<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>

修改:真实代码

对话框模板:

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

详细任务对话框:

<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,
  },

我想避免在View中传递prop,但是我不知道如何://很遗憾,我没有读过'slot-scope'。如何实现这种功能?

1 个答案:

答案 0 :(得分:2)

编辑:真实代码

根据您的真实世界代码,您仅缺少范围的附件,请参见下文。

对话框模板:

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

详细任务对话框:

<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>

如果您想在aaa组件中使用task-details-form,我仍然下注,您必须将它作为道具传递下来。但这对我来说很奇怪,因为我现在不确定执行顺序(v槽与v-bind),但是可以这样尝试:

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

编辑2:经过测试

v-bind速记不适用于<slot>

对话框模板:

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

详细任务对话框:

<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>

原文:

我认为您误解了插槽。检查文档:

该插槽可以访问与模板其余部分相同的实例属性(即相同的“作用域”)。该广告位无法访问孩子的范围。

Slots

所以您可以这样做,但是您的代码变为:

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

公司:

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

如果您按照建议在frm上定义一个插槽,则可以使用特定模板填充该插槽,并且可以接收(!)该插槽的范围。

您提到的已弃用的插槽范围将为您提供与孩子绑定的上下文,以便您将其暴露在父级的主要插槽中,这与您想要的相反。

出于好奇,为什么不将对话框数据作为属性发送到表单?这就是它的目的。