从组件内部的组件调用方法 <slot></slot>

Call method from component inside component's <slot></slot>

我正在学习 Vue.js,并且正在努力寻找组织代码的方法。我试图让一切尽可能模块化,所以在制作滑块时我做了以下事情:

<template>
    <div class="banners">
        <slot></slot>
    </div>
</template>
<script>
    export default {
        methods: {
            echo() {
                console.log('Echoing..')
            }
        },
        mounted() {
            $('.banners').slick();
        }
    }
</script>

在我看来,我只是使用组件:

<banners>
    <?php for ($i = 0; $i < 5; $i++) : ?>
        <img src="http://lorempixel.com/1440/500" alt="Banner image" class="banner">
        <a href="#" v-on:click="echo">Echo</a>
    <?php endfor; ?>
</banners>

但是在我尝试调用 echo 之后,它会在父范围内查找它,而不是在 banners 组件范围内,并且说方法未定义。

我想知道实现它的最佳方法。在父范围内声明方法对我来说是无用的,因为在我的项目中将有数百万其他方法与这种情况类似,如果我这样做,它会很快变得杂乱无章。我想在它们自己的 whatever 中包含这些横幅方法,这样我就可以很容易地在适当的位置找到它们,以及除横幅之外的其他模块。

也许我使用组件的方式不对,不应该用于此目的?我只是不能在父范围内放置一个 echo() 方法来处理仅与该特定组件相关的内容。想象一下,也许我会在其他元素中使用其他 echo() 来做一些与横幅不同的事情。

我也无法移动模板中的 slot 内容,因为我需要通过 PHP 获取数据,这就是为什么我做了 forslot.

在这种特殊情况下,您应该使用 scoped slot

在您的组件中传递您希望能够在插槽中使用的属性(在本例中为 echo 方法)。

<div class="banners">
    <slot :echo="echo"></slot>
</div>

在您的应用模板中,使用范围为 属性.

的模板标签将要注入插槽的内容包裹起来
<banners>
    <template slot-scope="props">
    <?php for ($i = 0; $i < 5; $i++) : ?>
        <img src="http://lorempixel.com/1440/500" alt="Banner image" class="banner">
        <a href="#" v-on:click="props.echo">Echo</a>
    <?php endfor; ?>
    </template>
</banners>

这是一个example.

如果您不需要使用传递给插槽的所有内容或只是为了避免每次都写入 props.echo,您也可以解构作用域属性。

<banners>
    <template slot-scope="{echo}">
    <?php for ($i = 0; $i < 5; $i++) : ?>
        <img src="http://lorempixel.com/1440/500" alt="Banner image" class="banner">
        <a href="#" v-on:click="echo">Echo</a>
    <?php endfor; ?>
    </template>
</banners>

您也可以引用父组件。

<banners ref="TheBanner">
    <?php for ($i = 0; $i < 5; $i++) : ?>
        <img src="http://lorempixel.com/1440/500" alt="Banner image" class="banner">
        <a href="#" v-on:click="$refs.TheBanner.echo()">Echo</a>
    <?php endfor; ?>
</banners>