VueJS中的亲子沟通

时间:2017-09-01 19:09:56

标签: javascript vue.js vue-component

我有两个Vue组件。 parent-component

Vue.component('parent-component',{
        methods: {
            test: function(){
             alert('Option Selected');
            }
        },
        template: `
            <div><slot></slot></div>
        `
});

animals组件:

Vue.component('animals',{
        data: function(){
            return {
                selected: ''
            }
        },
        template: `
            <select @change="selectionChanged" v-model="selected">
                <slot></slot>
            </select>
        `,
        methods: {
            selectionChanged: function(){
                this.$emit('optionselected', this.selected);
            }
        }
 });

这是我的HTML:

<div id="app">
        <parent-component @optionselected="test()">
            <animals>
                <option>Aardvark</option>
                <option>Bear</option>
                <option>Cat</option>
            </animals>
        </parent-component>
 </div>

我正在尝试从子组件(animals)到父组件(parent-component)获取所选选项。我从子节点发出optionselected事件,但看起来父组件没有响应该事件,我的意思是方法test()根本没有被调用。我在这里做错了什么?

以下是JSFiddle Demo

1 个答案:

答案 0 :(得分:1)

首先,您需要将侦听器添加到模板中的animals组件。

<animals @optionselected="test">

其次,重要的是要记住,因为您正在使用 slots ,所以插槽内的元素将在定义它们的组件的范围内进行评估。在这种情况下,该范围是Vue的范围,而不是parent-component范围。为了允许槽内定义的元素使用包含组件的数据,方法等,您需要定义scoped slot。在这种情况下,您的父组件最终会如下所示:

<div><slot :test="test"></slot></div>

您的Vue模板变为

<parent-component>
  <template scope="{test}">
    <animals @optionselected="test">
      <option>Aardvark</option>
      <option>Bear</option>
      <option>Cat</option>
    </animals>
  </template>
</parent-component>

这是更新的代码。

&#13;
&#13;
console.clear()
Vue.component('parent-component', {
  methods: {
    test: function(option) {
      alert('Option Selected ' + option);
    }
  },
  template: `
            <div><slot :test="test"></slot></div>
        `
});
Vue.component('animals', {
  data: function() {
    return {
      selected: ''
    }
  },
  template: `
            <select @change="selectionChanged" v-model="selected">
                <slot></slot>
            </select>
        `,
  methods: {
    selectionChanged: function() {
      this.$emit('optionselected', this.selected);
    }
  }
});
new Vue({
  el: "#app",
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
  <parent-component>
    <template scope="{test}">
      <animals @optionselected="test">
        <option>Aardvark</option>
        <option>Bear</option>
        <option>Cat</option>
      </animals>
    </template>
  </parent-component>
</div>
&#13;
&#13;
&#13;