How to send data from the slot in Vue?

We know that using scoped slots can pass data to the slot, but how to pass it back from the slot?

Pass a method to our slot, and then call the method in the slot. I believe that the event cannot be emitted because the slot shares the same context (or scope) with the parent component.

// Parent.vue
<template>
  <Child>
    <template #default="{ clicked }">
      <button @click="clicked">
        Click this button
      </button>
    </template>
  </Child>
</template>
// Child.vue
<template>
  <div>
    <!-- 将“handleClick” 作为 “clicked” 传递到我们的 slot -->
    <slot :clicked="handleClick" />
  </div>
</template>

In this article, we will introduce how it works, as well as:

  • Emit from slot to parent
  • What does it mean when a slot shares scope with the parent component
  • Emit from slot to grandfather component
  • Have a deeper understanding of how to use methods to communicate back from the slot

 

Emit from slot to parent

Now look at the contents of the Parent component:

// Parent.vue
<template>
  <Child>
    <button @click="">
      Click this button
    </button>
  </Child>
</template>

We have a button in the slot of the Child component. When the button is clicked, we need to call a method inside the Parent component.

If the button is not in the slot, but directly in the child component of the Parent component, we can access the method on the component:

// Parent.vue
<template>
  <button @click="handleClick">
    Click this button
  </button>
</template>

The same is true when the button component is in the slot:

/ Parent.vue
<template>
  <Child>
    <button @click="handleClick">
      Click this button
    </button>
  </Child>
</template>

This is possible because the slot shares the same scope with the Parent component.

 

Slot and template scope

Template scope: All content inside the template can access all content defined on the component.

This includes all elements, all slots and all scoped slots.

Therefore, no matter where the button is located in the template, you can access the handleClick method.

At first glance, this may seem strange, and this is one of the reasons why slots are hard to understand. The slot is finally rendered as a child component of the Child component, but it does not share scope with the Child component. Instead, it acts as a child component of the Parent component.

 

The slot sends data to the grandfather component

If you want to send data from the slot to the grandfather component, the normal way is to use the $emit method:

// Parent.vue
<template>
  <Child>
    <button @click="$emit('click')">
      Click this button
    </button>
  </Child>
</template>

Because this slot shares the same template scope with the Parent component, calling $emit here will emit events from the Parent component.

 

Send back sub-components from the slot

How about communicating with the Child component?

We know how to pass data from child nodes to slots

// Child.vue
<template>
  <div>
    <slot :data="data" />
  </div>
</template>

And how to use it in a slot in the scope:

// Parent.vue
<template>
  <Child>
    <template #default="{ data }">
      {
   
   { data }}
    </template>
  </Child>
</template>

In addition to passing data , we can also pass methods to scope slots. If we connect these methods in the right way, we can use it to communicate with the Child component:

// Parent.vue
<template>
  <Child>
    <template #default="{ clicked }">
      <button @click="clicked">
        Click this button
      </button>
    </template>
  </Child>
</template>
// Child.vue
<template>
  <div>
    <!-- Pass `handleClick` as `clicked` into our slot -->
    <slot :clicked="handleClick" />
  </div>
</template>

Whenever the button is clicked, the handleClick method in the Child component is called

Guess you like

Origin blog.csdn.net/weixin_43844696/article/details/108200948