如何访问插槽中子组件的反应数据?

pet*_*ski 7 vue.js vuejs2 vuejs-slots

目前,我有一个父组件,它渲染一个子组件,并将一个组件(模态组件,称为 Modal.vue)作为插槽传递到子组件中。

家长.vue

<ChildComponent :id='1>
 <modal slot="modal" :postTitle="'test'" />
</ChildComponent>
Run Code Online (Sandbox Code Playgroud)

儿童.vue

export default {
props : ['id'],
data(){
return {
 modalHeading : "Heading"
}
}
<template>
<slot name="modal"></slot>
</template>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何访问插槽组件中子级的数据(和函数)?

我一直在尝试让它与作用域插槽一起使用,但似乎无法破解语法。

Mic*_*evý 7

我试图基本上在模式槽中显示一些子数据。本质上父组件是页面,子组件是表格,槽是模态框。对于单击的每个表行,都会出现一个模式,其中包含表数据。你建议怎样做

也许是这样的?

<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>
Run Code Online (Sandbox Code Playgroud)

我不明白这怎么有插槽的灵活性?

嗯,它不像插槽那么灵活,但它可以完成工作:)

如果您确实需要以允许在不同地方使用它并更改其部分外观(在您的情况下为行详细信息)的方式设计您的子/表组件,那么插槽是不错的选择......

老虎机

老虎机是内容的分发渠道。当您在组件中放置一个插槽时,您是在说“我的父组件可以提供部分模板。当呈现此模板时(在父组件范围内 -很重要,因为该模板只能访问父组件的数据/方法等),我将获取渲染结果并将其放在我自己的模板中的确切位置”。使用常规槽就像将 HTML 传递到组件中一样。

我的问题是,如何访问插槽组件中子级的数据(和函数)?

您必须显式地授予槽模板对某些子数据的访问权限。假设您的子组件有 prop item。您可以在其中定义范围插槽,如下所示:

<slot name="rowExpander" :itemProp="item"></slot>
Run Code Online (Sandbox Code Playgroud)

...并在父级内部使用它,如下所示:

<template v-slot:rowExpander="slotProps">
  <MyRowExpanderComponent :item="slotProps.itemProp" />
</template>
Run Code Online (Sandbox Code Playgroud)

或者使用ES2015解构

<template v-slot:rowExpander="{ itemProp }">
  <MyRowExpanderComponent :item="itemProp" />
</template>
Run Code Online (Sandbox Code Playgroud)

几乎可以将任何内容传递到范围槽中 - data/props/method/compulated,您甚至可以使用实例属性,例如$data$props

<slot name="rowExpander" :childProps="$props"></slot>
Run Code Online (Sandbox Code Playgroud)

不可能传递子实例本身:

<slot name="rowExpander" :child="this"></slot>
Run Code Online (Sandbox Code Playgroud)

(主要this是因为未在模板内定义 - 我认为如果您使用渲染函数编写没有模板的组件,这是可以完成的,但这是另一个故事)

重要的是要理解范围插槽模板只是常规的 Vue 模板。它可以访问定义它的组件(父组件)的所有实例属性,此外还可以访问slotProps对象。当您在作用域插槽模板中使用组件时,该组件无法访问所有子数据或slotProps 自动访问- 您仍然需要将其显式传递给它(就像MyRowExpanderComponent上面的示例一样)