簡體   English   中英

如何在父事件上調用子組件的函數

[英]How to call function on child component on parent events

語境

在 Vue 2.0 中,文檔和其他文檔清楚地表明,父母與孩子之間的交流是通過 props 發生的。

問題

父母如何通過道具告訴孩子事件發生了?

我應該只看一個叫做事件的道具嗎? 這感覺不對,替代方案也不對( $emit / $on用於子到父,集線器模型用於遠距離元素)。

例子

我有一個父容器,它需要告訴它的子容器可以在 API 上執行某些操作。 我需要能夠觸發功能。

給子組件一個ref並使用$refs直接調用子組件上的方法。

html:

<div id="app">
  <child-component ref="childComponent"></child-component>
  <button @click="click">Click</button>  
</div>

javascript:

var ChildComponent = {
  template: '<div>{{value}}</div>',
  data: function () {
    return {
      value: 0
    };
  },
  methods: {
    setValue: function(value) {
        this.value = value;
    }
  }
}

new Vue({
  el: '#app',
  components: {
    'child-component': ChildComponent
  },
  methods: {
    click: function() {
        this.$refs.childComponent.setValue(2.0);
    }
  }
})

有關更多信息,請參閱refs 上的 Vue 文檔

您所描述的是父母的狀態變化。 您通過道具將其傳遞給孩子。 正如你所建議的,你會watch那個道具。 當孩子采取行動時,它會通過emit通知父母,然后父母可能會再次改變狀態。

 var Child = { template: '<div>{{counter}}</div>', props: ['canI'], data: function () { return { counter: 0 }; }, watch: { canI: function () { if (this.canI) { ++this.counter; this.$emit('increment'); } } } } new Vue({ el: '#app', components: { 'my-component': Child }, data: { childState: false }, methods: { permitChild: function () { this.childState = true; }, lockChild: function () { this.childState = false; } } })
 <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script> <div id="app"> <my-component :can-I="childState" v-on:increment="lockChild"></my-component> <button @click="permitChild">Go</button> </div>

如果你真的想將事件傳遞給孩子,你可以通過創建一個總線(它只是一個 Vue 實例)並將其作為 prop 傳遞給孩子來做到這一點。

您可以使用$emit$on 使用@RoyJ 代碼:

html:

<div id="app">
  <my-component></my-component>
  <button @click="click">Click</button>  
</div>

javascript:

var Child = {
  template: '<div>{{value}}</div>',
  data: function () {
    return {
      value: 0
    };
  },
  methods: {
    setValue: function(value) {
        this.value = value;
    }
  },
  created: function() {
    this.$parent.$on('update', this.setValue);
  }
}

new Vue({
  el: '#app',
  components: {
    'my-component': Child
  },
  methods: {
    click: function() {
        this.$emit('update', 7);
    }
  }
})

運行示例: https ://jsfiddle.net/rjurado/m2spy60r/1/

在子組件上調用方法的簡單解耦方式是從子組件發出處理程序,然后從父組件調用它。

 var Child = { template: '<div>{{value}}</div>', data: function () { return { value: 0 }; }, methods: { setValue(value) { this.value = value; } }, created() { this.$emit('handler', this.setValue); } } new Vue({ el: '#app', components: { 'my-component': Child }, methods: { setValueHandler(fn) { this.setter = fn }, click() { this.setter(70) } } })
 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> <div id="app"> <my-component @handler="setValueHandler"></my-component> <button @click="click">Click</button> </div>

父進程跟蹤子處理函數並在必要時調用。

不喜歡在create期間在孩子中使用$on綁定的事件總線方法 為什么? 隨后的create調用(我正在使用vue-router )不止一次綁定消息處理程序——導致每條消息有多個響應。

將 props 從 parent 傳遞給 child 並在 child 中放置 property watcher 的正統解決方案效果更好一些 唯一的問題是孩子只能對價值轉變采取行動。 多次傳遞相同的消息需要某種簿記來強制轉換,以便孩子可以接受更改。

我發現如果我將消息包裝在一個數組中,它總是會觸發子觀察者——即使值保持不變。

家長:

{
   data: function() {
      msgChild: null,
   },
   methods: {
      mMessageDoIt: function() {
         this.msgChild = ['doIt'];
      }
   }   
   ...
}

孩子:

{
   props: ['msgChild'],
   watch: {
      'msgChild': function(arMsg) {
         console.log(arMsg[0]);
      }
   }
}

HTML:

<parent>
   <child v-bind="{ 'msgChild': msgChild }"></child>
</parent>

如果你有時間,可以使用 Vuex 存儲來觀察變量(又名狀態)或直接觸發(又名調度)一個動作。

下面的例子是自我解釋的。 其中 refs 和 events 可用於在父子之間調用函數。

// PARENT
<template>
  <parent>
    <child
      @onChange="childCallBack"
      ref="childRef"
      :data="moduleData"
    />
    <button @click="callChild">Call Method in child</button>
  </parent>
</template>

<script>
export default {
  methods: {
    callChild() {
      this.$refs.childRef.childMethod('Hi from parent');
    },
    childCallBack(message) {
      console.log('message from child', message);
    }
  }
};
</script>

// CHILD
<template>
  <child>
    <button @click="callParent">Call Parent</button>
  </child>
</template>

<script>
export default {
  methods: {
    callParent() {
      this.$emit('onChange', 'hi from child');
    },
    childMethod(message) {
      console.log('message from parent', message);
    }
  }
}
</script>

在父組件中調用子組件

<component :is="my_component" ref="my_comp"></component>
<v-btn @click="$refs.my_comp.alertme"></v-btn>

在子組件中

mycomp.vue

    methods:{     
    alertme(){
            alert("alert")
            }
    }

我認為我們應該考慮一下 parent 使用 child 的方法的必要性。實際上,父母不必關心 child 的方法,而是可以將 child 組件視為 FSA(finite state machine)。Parents 組件控制子組件的狀態。所以觀察狀態變化或只使用計算功能的解決方案就足夠了

您可以使用mixin設置共享數據屬性。 在父級中對其進行更改,在子級中對其進行監視:

// mixin
export default {
  data() {
    return  {
      clicked: false
    }
  }
}

// parent
export default {
  mixins: [myMixin],
  methods: {
    btnClick() {
      this.clicked = true
    }
  }
}

// child
export default {
  mixins: [myMixin],
  watch: {
    clicked(val) {
      if(val) {
        // yay
      }
    }
  }
}

您可以使用 key 使用 key 重新加載子組件

<component :is="child1" :filter="filter" :key="componentKey"></component>

如果要使用新過濾器重新加載組件,如果單擊按鈕過濾子組件

reloadData() {            
   this.filter = ['filter1','filter2']
   this.componentKey += 1;  
},

並使用過濾器觸發功能

您可以通過切換父級中的布爾屬性來模擬向子級發送事件。

父代碼:

...
<child :event="event">
...
export default {
  data() {
    event: false
  },
  methods: {
    simulateEmitEventToChild() {
      this.event = !this.event;
    },
    handleExample() {
      this.simulateEmitEventToChild();
    }
  } 
}

子代碼:

export default {
  props: {
    event: {
      type: Boolean
    }
  },
  watch: {
    event: function(value) {
      console.log("parent event");
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM