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

Posted

技术标签:

【中文标题】如何在 Vue.js 插槽范围内传递方法【英文标题】:How to pass a method in Vue.js slot scope 【发布时间】:2018-10-22 05:22:08 【问题描述】:

我在 vuejs 中使用插槽范围。它工作得很好。我可以像这样将任何我想要的东西传递到插槽中:

<slot :item1="item1">    
</slot>

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

<slot :my-method="myMethod">    
</slot>

在本例中,myMethod 是定义在子 vue 组件上的方法。 (我用的是typescript,所以是组件类上的一个方法)

关于如何通过 slot props 将子组件上定义的函数传递回父组件,以便可以从父组件的 slot 代码中调用它的任何想法?

【问题讨论】:

【参考方案1】:

根据所有答案,我试图在这里创建一个概念教授代码示例https://codesandbox.io/s/vuejs-v-slot-sample-z9r9c

我的意思是创建一个按钮组件,第二个使用插槽,最后一个带有第二个组件的第二个组件使用第一个按钮组件的插槽功能并与$emit功能连接在一起。

希望它有用。

【讨论】:

【参考方案2】:

阅读this article我发现如果你需要以编程方式调用一个方法(而不是从模板中),你实际上可以将一个方法从父组件传递给作用域槽,但是你必须传递相同的通过 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>

父组件(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>

子组件(Cart.vue)

<script>
    export default 
        name: 'Cart',
        props: ['myMethod'],
        mounted() 
            // here you call the method
            this.myMethod();
        
    ;
</script>

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

【讨论】:

【参考方案3】:

更新

这个答案是为旧的 pre 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>

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

<current-user>
  <template v-slot:default="slotProps">
     slotProps.user.firstName 
  </template>
</current-user>

这是一个更复杂的例子,你会注意到,函数和作用域槽是使用slotProps传递的


pre v2.6 语法的原始答案。如何传递slot-scope的示例

父母:

<template>
  <div slot="item" slot-scope=" myLink, myMethod ">
    <button @click="myMethod(myLink.title)">
      Bookmark
    </button>
  </div>
</template>

孩子:

<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>

【讨论】:

效果很好!我意识到我的问题是我搞砸了大写,所以当我将它们作为属性传递时,它们是未定义的。 请注意 slot scopes 在 Vue 2.6.x 版本中已被弃用(请参阅 vuejs.org/v2/guide/…),因此请使用新的推荐语法,您可以在此处找到 vuejs.org/v2/guide/components-slots.html#Scoped-Slots

以上是关于如何在 Vue.js 插槽范围内传递方法的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 3 - 将组件插入插槽

将插槽传递到 Vue.js 中的插槽

将父母道具传递给Vue,js中的插槽

Vue JS - 在插槽中改变传递的道具

Vue.js 将数据从插槽传递到组件实例

Vue.js 将插槽传递给包装好的 Bootstrap-Vue 表组件