如何在插槽中访问子组件的反应数据?
Posted
技术标签:
【中文标题】如何在插槽中访问子组件的反应数据?【英文标题】:How to access child component's reactive data in a slot? 【发布时间】:2020-03-23 05:20:29 【问题描述】:目前,我有一个父组件,它渲染一个子组件,同时也将一个组件(模态,称为 Modal.vue)作为插槽传递给子组件。
父.vue
<ChildComponent :id='1>
<modal slot="modal" :postTitle="'test'" />
</ChildComponent>
Child.vue
export default
props : ['id'],
data()
return
modalHeading : "Heading"
<template>
<slot name="modal"></slot>
</template>
Modal.vue
<script>
export default
name: "model",
props: ["postTitle"],
data()
return
heading: "test"
;
,
mounted()
console.log("mounted modal slot");
console.log(this.postTitle);
console.log(this.modalHeading);
;
</script>
<template>
<div>
<h2> modalHeading </h2>
<h3>This will be the modal slot</h3>
<p> postTitle </p>
</div>
</template>
我的问题是,如何在我的插槽组件中访问孩子的数据(和函数)?
我一直试图让它与作用域插槽一起工作,但似乎无法破解语法。
【问题讨论】:
您到底想达到什么目的?当然,作用域插槽可用于将 一些 的Child
组件数据共享到插槽 模板。但是功能呢?不要这么想。也仅仅因为您的 modal
组件在作用域插槽模板中使用并不能使其可以访问所有 Child
数据。您仍然需要通过道具将其传递给modal
....
我试图基本上在模态槽中显示一些子数据。本质上,父组件是一个页面,子组件是一个表格,插槽是一个模态。对于单击的每个表格行,都会出现一个模式,其中包含表格数据。你会如何建议这样做?
【参考方案1】:
我试图基本上在模态槽中显示一些子数据。本质上,父组件是一个页面,子组件是一个表格,插槽是一个模态。对于单击的每个表格行,都会出现一个模式,其中包含表格数据。你会如何建议这样做
也许是这样的?
<template>
<div>
<table>
<row v-for="item in items" @click="onRowClick(item)"
....show some data
</row>
</table>
<modal v-if="activeItem" :item="activeItem" @onClose="onModalClose" />
</div>
</template>
<script>
export default
name: 'child',
props: ["items"]
data()
return
activeItem: null
,
methods:
onRowClick(item)
this.activeItem = item;
,
onModalClose()
this.activeItem = null;
</script>
我不明白这怎么有插槽的灵活性?
嗯,它不像插槽那么灵活,但它可以完成工作:)
如果您真的需要以允许在不同位置使用它并更改其部分外观(在您的情况下为行详细信息)的方式设计您的 Child/table 组件,那么插槽就是方式走吧……
插槽
Slots 是内容的分发渠道。当您在组件内放置一个插槽时,您是在说“我的父组件可以提供部分模板。当此模板被渲染时(在父组件范围内 - 重要,因为该模板只能访问父组件的数据/methods 等),我会将渲染结果放在我自己的模板中在这个确切的位置”。使用常规插槽就像将 html 传递到您的组件中。
我的问题是,如何在我的 slot 组件中访问孩子的数据(和函数)?
您必须明确授予插槽模板访问某些孩子数据的权限。假设您的子组件有 prop item
。您可以像这样在其中定义 scoped slot:
<slot name="rowExpander" :itemProp="item"></slot>
...并像这样在父级中使用它:
<template v-slot:rowExpander="slotProps">
<MyRowExpanderComponent :item="slotProps.itemProp" />
</template>
或使用ES2015 destructuring
<template v-slot:rowExpander=" itemProp ">
<MyRowExpanderComponent :item="itemProp" />
</template>
几乎可以将任何内容传递到作用域插槽中 - 数据/道具/方法/计算,您甚至可以使用实例属性,例如 $data
或 $props
:
<slot name="rowExpander" :childProps="$props"></slot>
不能传递子实例本身:
<slot name="rowExpander" :child="this"></slot>
(主要是因为this
没有在模板中定义 - 我认为如果您使用渲染函数编写没有模板的组件可以做到,但这是另一回事)
了解作用域插槽模板只是普通的 Vue 模板很重要。它可以访问定义它的组件的所有实例属性(父)另外可以访问slotProps
对象。当您在作用域插槽模板中使用组件时,该组件 没有 访问所有子数据或 slotProps
自动魔术 - 您仍然需要将其传递给它明确的(就像我上面的MyRowExpanderComponent
示例)
【讨论】:
我不明白这怎么有插槽的灵活性?说,而不是在点击时出现模式,我希望行高扩大,另一个表格出现在点击的行下方。这怎么可能实现?我认为方法是将要作为插槽显示的组件解析到我的表格组件中? 阅读文档中的 Scoped Slot 以获取有关解决此类问题的更新:vuejs.org/v2/guide/components-slots.html#Scoped-Slots以上是关于如何在插槽中访问子组件的反应数据?的主要内容,如果未能解决你的问题,请参考以下文章