घटक के बाहर से Vue.js घटक विधि को कॉल करें


229

मान लीजिए कि मेरे पास एक मुख्य Vue उदाहरण है जिसमें बाल घटक हैं। क्या पूरी तरह से Vue उदाहरण के बाहर से इन घटकों में से एक को कॉल करने का एक तरीका है?

यहाँ एक उदाहरण है:

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()विधि इसके क्लिक इवेंट के लिए बाध्य होती है इसलिए इसे कॉल किया जाता है। ईवेंट को बाहरी बटन से बांधने का कोई तरीका नहीं है, जिसकी क्लिक ईवेंट मैं jQuery के साथ सुन रहा हूं, इसलिए मुझे कॉल करने के लिए किसी अन्य तरीके की आवश्यकता होगी increaseCount

संपादित करें

ऐसा लगता है कि यह काम करता है:

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

हालांकि, यह एक अच्छा समाधान नहीं है क्योंकि मैं बच्चों के सरणी में इसके सूचकांक द्वारा घटक का संदर्भ दे रहा हूं, और कई घटकों के साथ यह स्थिर रहने की संभावना नहीं है और कोड कम पठनीय है।


1
यदि आप इसे आज़माना चाहते हैं तो मैंने mxins का उपयोग करके एक उत्तर जोड़ा। मेरी राय में मैं ऐप को इस तरह सेटअप करना पसंद करता हूं।
उमर तांती

जवाबों:


275

अंत में मैंने Vue के refनिर्देश का उपयोग करने का विकल्प चुना । यह एक घटक को प्रत्यक्ष अभिगम के लिए माता-पिता से संदर्भित करने की अनुमति देता है।

उदाहरण के लिए

मेरे माता-पिता के उदाहरण पर एक शिकायत दर्ज की गई है:

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

एक संदर्भ के साथ टेम्पलेट / 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/ का उपयोग करके )


6
ऐसा इसलिए है क्योंकि आपने शायद इसे परिभाषित नहीं किया है। लिंक्ड फिडेल को देखें।
१२:४२

29
यदि आप वेबपैक का उपयोग कर रहे हैं तो आप vmजिस तरह से यह स्कोप मॉड्यूल है, उसके कारण आप एक्सेस नहीं कर पाएंगे । आप अपनी तरह window.app = vmसे कुछ कर सकते हैं main.js। स्रोत: forum.vuejs.org/t/how-to-access-vue-from-chrome-console/3606
tw airball

1
क्या इस दृष्टिकोण को सामान्य माना जा सकता है? या यह हैक है?
CENT1PEDE

3
हैक क्या है "सामान्य" कोडिंग क्या है इसकी इतनी आधिकारिक परिभाषा है, लेकिन इस दृष्टिकोण को कॉल हैक करने के बजाय (या एक ही चीज़ को प्राप्त करने के "कम-हैसी" तरीके के लिए देखें) यह सवाल करना बेहतर है कि आपको क्या करने की आवश्यकता है यह। कई मामलों में बाहरी घटक व्यवहार को ट्रिगर करने के लिए Vue के इवेंट सिस्टम का उपयोग करना अधिक सुरुचिपूर्ण हो सकता है, या यह भी पूछ सकते हैं कि आप घटकों को बाहरी रूप से क्यों ट्रिगर कर रहे हैं।
हर

8
यदि आप किसी दृश्य घटक को पहले से मौजूद पृष्ठ में एकीकृत करने का प्रयास कर रहे हैं तो यह सामने आ सकता है। पृष्ठ को पूरी तरह से नया स्वरूप देने के बजाय, कभी-कभी वृद्धिशील रूप से अतिरिक्त कार्यक्षमता जोड़ना अच्छा होता है।
एलन वांग

37

Vue2 के बाद से यह लागू होता है:

var bus = new Vue()

// घटक ए की विधि में

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

// घटक B के बनाए गए हुक में

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

  // ...
})

Vue डॉक्स के लिए यहां देखें । और यहां इस घटना को बस की स्थापना करने के तरीके के बारे में अधिक विस्तार से बताया गया है।

यदि आप गुण, घटनाओं और / या केंद्रीकृत राज्य प्रबंधन का उपयोग करने के बारे में अधिक जानकारी चाहते हैं, तो इस लेख को देखें


1
छोटा एवं सुन्दर! यदि आप वैश्विक busवैरिएबल को नापसंद करते हैं , तो आप एक कदम आगे जा सकते हैं और प्रॉप्स का उपयोग करके बस को अपने घटक में इंजेक्ट कर सकते हैं । मैं अपेक्षाकृत नया हूँ, इसलिए मैं आपको विश्वास नहीं दिला सकता कि यह मुहावरा है।
byxor

31

आप Vue इवेंट सिस्टम का उपयोग कर सकते हैं

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

तथा

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

यहाँ फिडेल है: http://jsfiddle.net/hfalucas/wc1gg5v4/59/


5
@GusDeCooL का उदाहरण संपादित किया गया है। ऐसा नहीं है कि Vuejs 2.0 के बाद इस्तेमाल किए गए कुछ तरीकों को हटा दिया गया है
हेल्डर लुकास

1
अच्छी तरह से काम करता है अगर घटक का केवल 1 उदाहरण है, लेकिन अगर कई उदाहरण हैं, तो $ refs.component.method () का बेहतर उपयोग करता है
Koronos

22

स्वीकृत उत्तर का थोड़ा अलग (सरल) संस्करण:

मूल उदाहरण पर एक घटक पंजीकृत है:

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

एक संदर्भ के साथ टेम्पलेट / html में घटक को प्रस्तुत करें:

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

घटक विधि तक पहुँचें:

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

22

आप बच्चे के घटकों के लिए रेफरी सेट कर सकते हैं फिर माता-पिता $ रेफ के माध्यम से कॉल कर सकते हैं:

चाइल्ड कंपोनेंट में रेफरी जोड़ें:

<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>
  <button id="external-button" @click="$refs.childref.increaseCount()">External Button</button>
</div>
  
<template id="my-template">
  <div style="border: 1px solid; padding: 2px;" ref="childref">
    <p>A counter: {{ count }}</p>
    <button @click="increaseCount">Internal Button</button>
  </div>
</template>


2
अब तक का सबसे साफ समाधान।
grreeenn

बहुत बढ़िया जवाब। मैं बस html को संपादित करने जा रहा हूँ थोड़ा लंबवत। वर्तमान में मैं केवल 'आंतरिक बटन' देख सकता हूं जब मैं इसे चलाता हूं जो भ्रमित हो सकता है।
जेसी रेजा

8

कहो कि आपके पास एक 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()

नोट: यह इस तरह से बच्चे और माता पिता के घटक का उपयोग करने के लिए अनुशंसित नहीं है।

इसके बजाय माता-पिता के बच्चे के संचार के लिए सबसे अच्छा अभ्यास प्रॉप्स एंड इवेंट्स का उपयोग करें।

यदि आप घटकों के बीच संचार चाहते हैं तो निश्चित रूप से vuex या इवेंट बस का उपयोग करें

कृपया इसे बहुत ही उपयोगी लेख पढ़ें



हां, आप कर सकते हैं, लेकिन 'सर्वोत्तम अभ्यास' नहीं माना जाता है: बाल उपयोग गुणों के लिए नीचे, माता-पिता की घटनाओं के लिए ऊपर की ओर। 'साइडवार्ड' को कवर करने के लिए, कस्टम इवेंट्स या उदाहरण के लिए vuex का उपयोग करें। अधिक जानकारी के लिए यह अच्छा लेख देखें ।
म्यूजिकफॉर्मेलन

हां ऐसा करने की अनुशंसा नहीं की गई है।
रोली रोली

3

यह एक घटक के तरीकों को अन्य घटक से एक्सेस करने का एक सरल तरीका है

// 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');
   }
}


1

मुझे यकीन नहीं है कि यह सही तरीका है लेकिन यह मेरे लिए काम करता है।
पहले उस घटक को आयात करें जिसमें वह विधि है जिसे आप अपने घटक में कॉल करना चाहते हैं

import myComponent from './MyComponent'

और फिर MyCompenent के किसी भी तरीके को कॉल करें

myComponent.methods.doSomething()

यह आपको अपने घटक के किसी भी डेटा तक पहुंच नहीं देता है। यदि आपका doSomethingडेटा से किसी भी चीज का उपयोग कर रहा है, तो यह विधि बेकार है।
सायबॉशू

-7

मैंने एक बहुत ही सरल उपाय का उपयोग किया है। मैंने एक HTML तत्व शामिल किया है, जो विधि को कॉल करता है, मेरे Vue घटक में जो मैं चुनता हूं, वेनिला JS का उपयोग करता हूं, और मैं क्लिक ट्रिगर करता हूं!

Vue Component में, मैंने कुछ इस तरह से शामिल किया है:

<span data-id="btnReload" @click="fetchTaskList()"><i class="fa fa-refresh"></i></span>

मैं वेनिला JS का उपयोग कर रहा हूं:

const btnReload = document.querySelector('[data-id="btnReload"]');
btnReload.click();                

यह विशेष रूप से ओपी के प्रश्न के संदर्भ में, विशेष रूप से प्रतिज्ञा के भीतर अच्छा व्यवहार नहीं माना जाता है।
हाइब्रिड वेब देव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.