首先来思考一个问题:是否有一种方法可以从子组件填充父组件的插槽?
最近一位同事问我这个问题,答案很简单:可以的。但我的解决方案可能和你想的完全不一样,这是涉及一个棘手的Vue架构问题,但也是一个非常有趣的问题。
<强>为什么会有这个问题强>
在我们的应用程序中,我们有一个顶部栏,其中包含不同的按钮,搜索栏和其他一些控件。根据每个人所在的页面,它可能略有不同,因此我们需要一种基于每个页面配置它的方法。
为此,我们希望每个页面都能够配置操作栏。看起来很简单,但这里有个问题
这个顶部栏(我们称之为<代码> ActionBar> 代码)实际上是我们的主布局的一部分,结构如下:
& lt; template> & lt; div> & lt; FullPageError/比; & lt; ActionBar/比; & lt; App/比; & lt;/div> & lt;/template>
根据你所在的页面/路线动态注入<代码>软件> 代码的位置。
我们可以使用<代码> ActionBar> 代码上的一些插槽来配置它。但是,我们如何从<代码>软件> 代码组件中控制这些插槽?
<强>定义问题强>
首先,最好是尽可能清楚地知道我们要解决的问题。
我们来看一个具有一个子组件和一个插槽的组件:
//Parent.vue & lt; template> & lt; div> & lt;孩子/比; & lt;槽/比; & lt;/div> & lt;/template>
我们可以这样填充<代码> 代码>的母公司插槽:
//App.vue & lt; template> & lt; Parent> & lt; p>这些内容进入slot & lt;/Parent> & lt;/template>
这里没什么特别的…
填充子组件的插槽很容易,这也是使用插槽的最常见方式。
但是,有没有一种方法可以控制从<代码>子> 代码组件内部进入父母<代码> 代码>组件<代码>槽> 代码的内容呢?
换种说法:我们可以让子组件填充父组件的插槽吗?来看看我想到的第一个解决方案。
<强>向下使用道具,向上使用事件强>
数据流经组件树的唯一途径是使用<代码>道具> 代码。而向上通信的方法是使用事件。这意味着,如果要让子组件与父组件进行通信,我们需要使用事件来实现。
因此,我们将使用事件来将内容传递到<代码> ActionBars 代码>槽中
从“进口SlotContent。/SlotContent '; 出口默认{ 名称:“应用程序”, 创建(){//当该组件是创建我们发出事件 这一点。美元发出(slot-content, SlotContent); }};
我们将要放入插槽中的所有内容打包到<代码> SlotContent> 代码组件中。一旦创建了应用程序组件,我们就会发出<代码> slot-content 代码>事件,并传递我们要使用的组件。
我们的组件结构如下:
& lt; template> & lt; div> & lt; FullPageError/比; & lt; ActionBar> & lt;组件:=" slotContent "/比; & lt;/ActionBar> & lt;应用@slot-content="组件=比;slotContent=组件/比; & lt;/div> & lt;/template>
监听该事件,并将<代码> slotContent 代码>设置为我们的<代码>软件> 代码组件发送给我们的任何内容,然后,使用内置的<代码>组件> 代码,就可以动态地渲染该组件。
但是,通过事件传递组件感觉很奇怪,并非是主流的做法。幸运的是,还有一种方法可以完全避免使用事件。
<强>使用美元选择强>
由于Vue组件只是JS对象,因此我们可以向它们添加所需的任何属性。无需使用事件传递插槽内容,我们只需将其作为字段添加到组件中即可:
//App.vue 从“进口SlotContent。/SlotContent '; 出口默认{ 名称:“应用程序”, slotContent: slotContent, 道具:{/* * */}, 计算:{/* * */},};
在主页中通过<代码>应用程序。slotContent 代码>获取对应的组件