【问题标题】:Vue triggering function with params from child unexpectedVue触发功能与子意外参数
【发布时间】:2019-07-04 04:33:46
【问题描述】:

我有以下组件:

<template>
  <button class="button" @[click]="action">{{ text }}</button>
</template>

<script>
export default {
  name: "Button",
  props: {
    action: {
      type: Function,
      required: false
    },
    text: {
      type: String,
      required: true
    },
    inputType: {
      type: String,
      required: false
    }
  },
  computed: {
    click() {
      return this.action ? "click" : null;
    }
  }
};
</script>

但是,当我将函数作为带有参数的action 传递时,该函数已在渲染时触发。没有参数也可以正常工作。

<v-button inputType="button" :action="say('Hello')" text="Alert" />
<v-button inputType="button" :action="say" text="Alert" />

触发函数:

say(message) {
    alert(message);
}

你可以看到here的行为。看着this,我希望它可以与传递参数一起使用。

所以我的问题是如何防止在渲染时触发?

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    使用$emit

    您可以发出clicked 事件,而不是将函数传递给子组件;例如:

    <button class="button" @click="$emit('clicked')">{{ text }}</button>
    

    然后监听组件本身发出的事件,触发你的函数:

    <v-button inputType="button" @clicked="say('Hello')" text="Alert" />
    

    虽然发出和处理事件是从子组件与其父组件进行通信的一种简洁方式,但当发出事件的组件不是直接后代时,它可能会有些崩溃;例如:组件是孙子。

    Vue 不会通过组件树隐式地冒泡事件,我相信这是为了确保事件行为是明确的。

    使用&lt;slot&gt;

    在这种情况下,通常希望使用slots 创建一个组件,以访问创建它的范围,然后将其嵌套在另一个子组件中。

    <modal>
      <v-button @clicked="say('hi)" text="Alert"/>
    </modal>
    

    使用高阶函数

    否则,如果您需要将函数传递给子组件,并且该函数也有参数,则必须将其创建为高阶函数。

    在您的情况下,您想将 say 方法传递给一个孩子,并带有一个参数。您想传递函数但不调用它,但是当您将参数传递给 say() 时,您会在那里调用它,然后:

    <v-btn :action="say('hi')">
    

    这里的解决方案是重写say,这样它也返回一个函数,然后当按钮被点击时会被调用:

    say (message) {
      return () => alert(message)
    }
    

    这意味着您必须在将say 方法传递给按钮组件时调用它,即使您没有将message 传递给该按钮实例。因此,以下将起作用:

    <v-button :action="say()" text="Alert"/>
    

    但这不会因为它不调用内部函数:

    <v-button :action="say" text="Alert"/>
    

    希望这会有所帮助:)

    【讨论】:

    • 我对这个解决方案有一个问题。例如,当在对话框组件中使用按钮时,我将函数传递给对话框和按钮。这在以前有效时不起作用。
    • 因此,如果我理解正确,您是在尝试将一个函数传递给按钮,这实际上是一个孙子组件,因为它是一个模态组件的子组件?当然(我是按设计理解的)Vue 自定义事件不会通过多个组件冒泡。
    • 如果是这样,那么一种解决方案是使用&lt;slot&gt; 在父范围内创建子组件并将它们组合到其他子组件中—example here。在这个例子中,我们在App 组件中创建了几个Button 组件,然后将它们传递给Modal 组件。 Button 组件仍然可以调用在 App 中定义的 say() 方法,因为它们是在其中创建的。
    • 还有scoped slots,当您想要做相反的事情并确保插槽内容可以访问它们插入的组件的数据时。
    • 现在——说了这么多,你可以通过将say变成一个高阶函数来真正实现你最初的要求。 Example here。我之前没有建议这样做,因为发出的事件似乎更像是解决您问题的“Vue 方式”。
    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 2020-08-03
    • 2020-12-06
    相关资源
    最近更新 更多