如何在Vue.js插槽范围内传递方法

use*_*723 7 vue.js

我在vuejs中使用插槽范围。效果很好。我可以将想要的任何东西传递到插槽中,如下所示:

<slot :item1="item1">    
</slot>
Run Code Online (Sandbox Code Playgroud)

问题是当我将函数作为道具传递时,在父模板中未定义该函数。所以这不起作用:

<slot :my-method="myMethod">    
</slot>
Run Code Online (Sandbox Code Playgroud)

在此示例中,myMethod是在子vue组件上定义的方法。(我正在使用打字稿,所以它是组件类上的一种方法)

关于如何将在子组件上定义的功能通过插槽属性传递回父级的任何想法,以便可以从父级的插槽代码中调用它?

Dan*_*iel 6

更新

该答案是针对较早的v2.6以前的语法编写的。从那时起,此语法已标记为不推荐使用。核心功能保持不变,功能(方法)与向上绑定的属性(从子级到父级)的工作方式相同,但是v-slot:default现在使用定义。

根据更新的文档(https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots),

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>
Run Code Online (Sandbox Code Playgroud)

绑定到元素的属性称为插槽道具。现在,在父级作用域中,我们可以使用带有值的v-slot来定义所提供的插槽道具的名称:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>
Run Code Online (Sandbox Code Playgroud)

您将注意到,这是一个更复杂的示例,该函数和作用域插槽使用 slotProps
编辑Vue模板


v2.6之前的语法的原始答案。如何通过示例slot-scope

父母:

<template>
  <div slot="item" slot-scope="{ myLink, myMethod }">
    <button @click="myMethod(myLink.title)">
      Bookmark
    </button>
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

儿童:

<template>
  <li v-for="myLink in links">
    <slot name="myLink" :myLink="myLink" :myMethod="myMethod"></slot>
  </li>
</template>

<script>
export default {
  methods: {
    myMethod(link) {
      link.bookmarked = true
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

Adam Wathan最近发布了一篇文章,该文章在https://adamwathan.me/renderless-components-in-vuejs/中显示了它的工作原理


Gio*_*sta 6

阅读这篇文章我发现如果您需要以编程方式(而不是从模板中)调用一个方法,您实际上可以将一个方法从父组件传递到作用域插槽,但是您必须将相同的方法传递给子组件通过 prop 的组件:通过这种方式,您可以访问该方法,并且可以从代码中调用它。

这是我使用它的方式:

用法(在 html、blade 或其他 vue 组件中)

<template>
    <cart-validation>
        <template v-slot:trigger="{ myMethod }">
            <!-- here you pass the method as a prop -->
            <cart :my-method="myMethod">
            </cart>
        </template>
    </cart-validation>
</template>
Run Code Online (Sandbox Code Playgroud)

父组件(CartValidation.vue)

<template>
    <div>
        <slot name="trigger" :my-method="myMethod" />
    </div>
</template>
<script>
    export default {
        name: 'CartValidation',
        methods: {
            myMethod() {
                // here you define your method
                console.log('hello!');
            }
        },
    };
</script>
Run Code Online (Sandbox Code Playgroud)

子组件(Cart.vue)

<script>
    export default {
        name: 'Cart',
        props: ['myMethod'],
        mounted() {
            // here you call the method
            this.myMethod();
        }
    };
</script>
Run Code Online (Sandbox Code Playgroud)

在我代码的其他部分,我使用了插槽内的其他元素,但在每个子组件中,我可以调用this.myMethod(). 我希望这可以帮助其他人:)