web-dev-qa-db-ja.com

コンポーネントの外部からVue.jsコンポーネントメソッドを呼び出す

子コンポーネントを持つメインのVueインスタンスがあるとしましょう。 Vueインスタンスの外部からこれらのコンポーネントの1つに属するメソッドを完全に呼び出す方法はありますか?

これが一例です。

var vm = new Vue({
  el: '#app',
  components: {
    'my-component': { 
      template: '#my-template',
      data: function() {
        return {
          count: 1,
        };
      },
      methods: {
        increaseCount: function() {
          this.count++;
        }
      }
    },
  }
});

$('#external-button').click(function()
{
  vm['my-component'].increaseCount(); // This doesn't work
});
<script src="http://vuejs.org/js/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app">
  
  <my-component></my-component>
  <br>
  <button id="external-button">External Button</button>
</div>
  
<template id="my-template">
  <div style="border: 1px solid; padding: 5px;">
  <p>A counter: {{ count }}</p>
  <button @click="increaseCount">Internal Button</button>
    </div>
</template>

内部ボタンをクリックすると、increaseCount()メソッドはclickイベントにバインドされるので、呼び出されます。このイベントをjQueryでリッスンしている外部ボタンにイベントをバインドする方法はありませんので、increaseCountを呼び出すには他の方法が必要になります。

_編集_

これはうまくいくようです:

vm.$children[0].increaseCount();

ただし、children配列内のインデックスでコンポーネントを参照しているため、これは適切な解決策ではありません。多くのコンポーネントでは、定数を維持することはほとんどなく、コードは読みにくくなります。

139
harryg

結局、 Vueのrefディレクティブ を使うことにしました。これにより、直接アクセスのためにコンポーネントを親から参照することができます。

例えば。

私の親インスタンスに登録されたコンピテンシーを持っています:

var vm = new Vue({
    el: '#app',
    components: { 'my-component': myComponent }
});

参照を使用してtemplate/html内のコンポーネントをレンダリングします。

<my-component ref="foo"></my-component>

今、他の場所で私は外部からコンポーネントにアクセスすることができます

<script>
vm.$refs.foo.doSomething(); //assuming my component has a doSomething() method
</script>

例として、このフィドルを参照してください。 https://jsfiddle.net/xmqgnbu3/1/

(Vue 1を使った古い例: https://jsfiddle.net/6v7y6msr/ /)

189
harryg

あなたはVueイベントシステムを使用することができます

vm.$broadcast('event-name', args)

そして

 vm.$on('event-name', function())

これはフィドルです: http://jsfiddle.net/hfalucas/wc1gg5v4/59/

26
Helder Lucas

Vue2以降、これが適用されます。

var bus = new Vue()

//コンポーネントAのメソッド内

bus.$emit('id-selected', 1)

//コンポーネントBの作成済みフック内

bus.$on('id-selected', function (id) {

  // ...
})

Vueのドキュメントについては ここ を参照してください。そして ここ は、このイベントバスを正確に設定する方法についての詳細です。

プロパティ、イベント、集中管理を使用するタイミングについてもっと知りたい場合は、 この記事 を参照してください。

19
musicformellons

子コンポーネントにrefを設定してから、親で$ refsを介して呼び出すことができます。

子コンポーネントに参照を追加します。

<my-component ref="childref"></my-component>

クリックイベントを親に追加します。

<button id="external-button" @click="$refs.childref.increaseCount()">External Button</button>
var vm = new Vue({
  el: '#app',
  components: {
    'my-component': { 
      template: '#my-template',
      data: function() {
        return {
          count: 1,
        };
      },
      methods: {
        increaseCount: function() {
          this.count++;
        }
      }
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  
  <my-component ref="childref"></my-component>
  <br>
  <button id="external-button" @click="$refs.childref.increaseCount()">External Button</button>
</div>
  
<template id="my-template">
  <div style="border: 1px solid; padding: 5px;" ref="childref">
    <p>A counter: {{ count }}</p>
    <button @click="increaseCount">Internal Button</button>
  </div>
</template>
6
Cong Nguyen

子コンポーネントにchild_method()があるとします。

export default {
    methods: {
        child_method () {
            console.log('I got clicked')
        }
    }
}

今度は、親コンポーネントからchild_methodを実行します。

<template>
    <div>
        <button @click="exec">Execute child component</button>
        <child-cmp ref="child"></child_cmp> <!-- note the ref="child" here -->
    </div>
</template>

export default {
    methods: {
        exec () { //accessing the child component instance through $refs
            this.$refs.child.child_method() //execute the method belongs to the child component
        }
    }
}

子コンポーネントから親コンポーネントのメソッドを実行したい場合:

this.$parent.name_of_method()

注:このように子コンポーネントと親コンポーネントにアクセスすることはお勧めできません。

代わりに、ベストプラクティスとして、親子コミュニケーションにProps&Eventsを使用してください。

コンポーネント間の通信が確実に必要な場合は vuex または イベントバス

これを読んでください非常に役に立つ article


3
roli roli

これは他のコンポーネントからコンポーネントのメソッドにアクセスする簡単な方法です。

// This is external shared (reusable) component, so you can call its methods from other components

export default {
   name: 'SharedBase',
   methods: {
      fetchLocalData: function(module, page){
          // .....fetches some data
          return { jsonData }
      }
   }
}

// This is your component where you can call SharedBased component's method(s)
import SharedBase from '[your path to component]';
var sections = [];

export default {
   name: 'History',
   created: function(){
       this.sections = SharedBase.methods['fetchLocalData']('intro', 'history');
   }
}
2
Dotnetgang

受け入れられている答えの、少し異なる(より単純な)バージョン:

コンピテンシーを親インスタンスに登録させます。

export default {
    components: { 'my-component': myComponent }
}

参照を使用してtemplate/html内のコンポーネントをレンダリングします。

<my-component ref="foo"></my-component>

コンポーネントメソッドにアクセスする

<script>
    this.$refs.foo.doSomething();
</script>
1
Victor

これは簡単なものです

this.$children[indexOfComponent].childsMethodName();
0
Pratik Khadtale