父槽中的可重用组件访问子方法

时间:2017-07-19 13:28:46

标签: javascript vue.js vuejs2 vue-component

假设我有一个组件Reusable,其方法onClick设置数据道具。我希望这个组件可以重用,我想使用插槽来覆盖部件。

据我了解正典,我必须将onClick方法作为范围属性从parent传递到reusable

<div class="reusable">
    <h2>Reusable</h2>
    <slot name="clicker" v-bind:onClick="onClick">
        Default stuff <button v-on:click="onClick">Close</button>
    </slot>
    <p v-if="clicked">You clicked me</p>
</div>

<div class="parent">
    <h1>Parent</h1>
    <reusable>
        <template slot="clicker" scope="reusable">
            <button click="reusable.onClick">
                Close from parent
            </button>
        </template>
    </reusable>
</div>

如果我有很多方法,这可能会变得冗长和嘈杂,我想知道:有更好的方式,还是这完全是cromulent?

我已经看过使用refs,并在父调用this.$refs.reusable.onClick上使用方法,以及指定动态组件并将其交换出来;两者似乎都违反直觉。

2 个答案:

答案 0 :(得分:3)

您可以使用对象表示法绑定插槽的属性:

<slot name="clicker" v-bind="{ onClick, onInput, onCustom }">
    Default stuff <button v-on:click="onClick">Close</button>
</slot>

Here's a working fiddle.

如果它变得过于冗长,你至少可以将对象定义移动到数据属性并将其从模板中取出:

<slot name="clicker" v-bind="scopeProps">
    Default stuff <button v-on:click="onClick">Close</button>
</slot>
data() {
  return {
    scopeProps: {
      onClick: this.onClick,
      onInput: this.onInput,
      onCustom: this.onCustom
    }
  }
}

答案 1 :(得分:0)

假设我们有两个名为 reusable parent 的组件。

<强> reusable.vue

<template>
  <div class="reusable">
      <h2>Reusable</h2>
      <slot name="clicker">
          Default stuff <button v-on:click="handleClick">Close</button>
      </slot>
      <p v-if="clicked">You clicked me</p>
  </div>
</template>

<script>
export default {
  params: {
    onClick: {
      type: Function,
      default() {}
    }
  }
  
  methods: {
    handleClick() {
      // default codes to execute goes here
      // then call onClick() callback
      this.onClick();
    }
  }
}
</script>

<强> parent.vue

<template>
  <div class="parent">
      <h1>Parent</h1>
      <reusable :on-click="onClickHandler">
          <template slot="clicker">
              // other codes for injecting to slot
          </template>
      </reusable>
  </div>
</template>

<script>
import reusable from './path/to/reusable.vue';

export default {
  components: { reusable },
  
  methods: {
    onClickHandler() {
      // stuff to be run when button in 'reusable' got clicked
    }
  }
}
</script>

这是您的用例的一种可能解决方案。