Vue.js में घटकों को डेटा पास करना


92

मैं कैसे vue.js. में घटकों के बीच डेटा पास करने के लिए समझने के लिए संघर्ष कर रहा हूँ मैंने कई बार डॉक्स के माध्यम से पढ़ा है और कई संबंधित प्रश्नों और ट्यूटोरियल को देखा है, लेकिन मुझे अभी भी यह नहीं मिल रहा है।

इसके चारों ओर अपना सिर लपेटने के लिए, मैं एक बहुत सरल उदाहरण को पूरा करने में मदद की उम्मीद कर रहा हूं

  1. एक घटक में उपयोगकर्ताओं की एक सूची प्रदर्शित (किया)
  2. लिंक पर क्लिक करने (किए जाने) के लिए उपयोगकर्ता डेटा को एक नए घटक पर भेजें - नीचे अपडेट देखें।
  3. उपयोगकर्ता डेटा संपादित करें और इसे मूल घटक पर भेजें (यह अब तक प्राप्त नहीं हुआ है)

यहाँ एक फील है, जो स्टेप टू पर फेल है: https://jsfiddle.net/retrogradMT/d1a8ips0/

मैं समझता हूं कि मुझे नए घटक को डेटा पास करने के लिए प्रॉपर का उपयोग करने की आवश्यकता है, लेकिन मुझे यकीन नहीं है कि यह कार्यात्मक रूप से कैसे किया जाए। मैं डेटा को नए घटक से कैसे बाँधूँ?

HTML:

    <div id="page-content">
       <router-view></router-view>
     </div>

 <template id="userBlock" >
   <ul>
     <li v-for="user in users">{{user.name}} - <a v-link="{ path: '/new' }"> Show new component</a>
     </li>
   </ul>
 </template>

  <template id="newtemp" :name ="{{user.name}}">
    <form>
      <label>Name: </label><input v-model="name">
      <input type="submit" value="Submit">
    </form>
  </template>

मुख्य घटक के लिए js:

Vue.component('app-page', {
  template: '#userBlock',

  data: function() {
    return{

        users: []
      }
    },

ready: function () {
    this.fetchUsers();
},

methods: {
    fetchUsers: function(){
        var users = [
          {
            id: 1,
            name: 'tom'
          },
          {
            id: 2,
            name: 'brian'
          },
          {
            id: 3,
            name: 'sam'
          },
        ];

        this.$set('users', users);
     }
    }
  })

दूसरे घटक के लिए JS:

Vue.component('newtemp', {
  template: '#newtemp',
  props: 'name',
  data: function() {
    return {
        name: name,
        }
   },
})

अपडेट करें

ठीक है, मुझे दूसरा चरण मिल गया है। यहाँ एक नई फ़िडेल है जो प्रगति दिखा रही है: https://jsfiddle.net/retrogradMT/9pffnmjp/

क्योंकि मैं वी-राउटर का उपयोग कर रहा हूं, मैं डेटा को एक नए घटक पर भेजने के लिए प्रॉपर का उपयोग नहीं करता हूं। इसके बजाय, मुझे वी-लिंक पर सेट परमर्स चाहिए और फिर इसे स्वीकार करने के लिए एक ट्रांज़िशन हुक का उपयोग करना चाहिए।

V- लिंक परिवर्तन vue- राउटर डॉक्स में नामित मार्गों को देखते हैं :

<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>

फिर घटक पर, मार्ग विकल्पों में डेटा जोड़ें संक्रमण हुक देखें :

Vue.component('newtemp', {
  template: '#newtemp',
  route: {
   data: function(transition) {
        transition.next({
            // saving the id which is passed in url
            name: transition.to.params.name
        });
     }
  },
 data: function() {
    return {
        name:name,
        }
   },
})

जवाबों:


46

------------- निम्नलिखित केवल Vue 1 के लिए लागू होता है --------------

पासिंग डेटा को कई तरीकों से किया जा सकता है। विधि उपयोग के प्रकार पर निर्भर करती है।


यदि आप एक नया घटक जोड़ते समय अपने html से डेटा पास करना चाहते हैं। यह सहारा का उपयोग किया जाता है।

<my-component prop-name="value"></my-component>

यह प्रोप वैल्यू आपके कंपोनेंट के लिए तभी उपलब्ध होगी जब आप प्रोप नाम prop-nameको अपनी propsविशेषता में जोड़ देंगे ।


जब किसी गतिशील या स्थैतिक घटना के कारण डेटा को एक घटक से दूसरे घटक में पारित किया जाता है। यह घटना प्रेषण और प्रसारकों का उपयोग करके किया जाता है। उदाहरण के लिए यदि आपके पास एक घटक संरचना है जैसे:

<my-parent>
    <my-child-A></my-child-A>
    <my-child-B></my-child-B>
</my-parent>

और तुम से डेटा भेजने के लिए चाहते हैं <my-child-A>के लिए <my-child-B>तो में <my-child-A>आप एक घटना प्रेषण करने के लिए करना होगा:

this.$dispatch('event_name', data);

यह कार्यक्रम सभी तरह से मूल श्रृंखला की यात्रा करेगा। और जो भी माता-पिता से आपके पास एक शाखा है, <my-child-B>आप डेटा के साथ घटना को प्रसारित करते हैं। तो जनक में:

events:{
    'event_name' : function(data){
        this.$broadcast('event_name', data);
    },

अब यह प्रसारण बाल श्रृंखला की यात्रा करेगा। और जिस भी बच्चे में आप इस घटना को पकड़ना चाहते हैं, हमारे मामले में <my-child-B>हम एक और घटना जोड़ेंगे:

events: {
    'event_name' : function(data){
        // Your code. 
    },
},

डेटा पास करने का तीसरा तरीका वी-लिंक में मापदंडों के माध्यम से है। इस विधि का उपयोग तब किया जाता है जब घटक श्रृंखलाएं पूरी तरह से नष्ट हो जाती हैं या ऐसे मामलों में जब यूआरआई बदलता है। और मैं देख सकता हूँ कि आप उन्हें पहले से ही समझ रहे हैं।


यह निर्धारित करें कि आपको किस प्रकार का डेटा संचार चाहिए, और उचित रूप से चुनें।


1
धन्यवाद, यह वास्तव में मददगार था। एकमात्र टुकड़ा जो मैं अभी भी संघर्ष कर रहा हूं, वह सम्मेलनों का नामकरण है। यानी: मेरे पास user.name है जो मैं नाम के रूप में v- लिंक से गुजरता हूं। मैं अब नाम चर को संपादित कर सकता हूं और मूल घटक पर वापस नाम के रूप में पास कर सकता हूं, लेकिन मूल घटक में एक var नाम नहीं है। मुझे यहां क्या समझ नहीं आ रहा है? क्या वी-लिंक के माध्यम से किसी वस्तु को पास करना संभव नहीं है?
— प्रतिगामी

1
आप पहले से ही एक ऑब्जेक्ट पास कर रहे हैं। paramsएक वस्तु है। this.user.nameआपके घटक में नाम कुंजी को असाइन किया जा सकता है । यदि आपको सहायता की आवश्यकता हो, तो एक फिडेल बनाएं और मुझे बताएं। इसे देखें: vuejs.github.io/vue-router/en/route.html
— notANerdDev

आह, ठीक है, मैं इसे अब मिल गया हूँ। एक बार फिर धन्यवाद। मैं आपकी मदद की सराहना करता हूं, यह वास्तव में चीजों को बहुत स्पष्ट करता है।
— प्रतिगामी

6
बहुत बढ़िया जवाब लेकिन जैसा कि मैं समझता हूं कि यह 2.0 के साथ काम नहीं करेगा क्योंकि घटनाओं को हटा दिया गया है?
— रिक्स

2
मुझे उत्तर पसंद आया लेकिन फिर टिप्पणियों में मिला और चूंकि मैं Vue 2 के साथ काम कर रहा हूं, मुझे लगता है कि मैं आपके द्वारा सुझाए गए दूसरे तरीके को सक्षम नहीं कर रहा हूं। क्या यह सही है?
— कोनराड विल्टर्स्टन

23

माता-पिता के घटक से बच्चे को डेटा भेजने का सबसे अच्छा तरीका प्रॉप्स का उपयोग करना है ।

माता-पिता से बच्चे के माध्यम से डेटा पास करना props

  • बच्चे में घोषणा props(सरणी या वस्तु )
  • इसके माध्यम से बच्चे को पास करें <child :name="variableOnParent">

नीचे डेमो देखें:

Vue.component('child-comp', {
  props: ['message'], // declare the props
  template: '<p>At child-comp, using props in the template: {{ message }}</p>',
  mounted: function () {
    console.log('The props are also available in JS:', this.message);
  }
})

new Vue({
  el: '#app',
  data: {
    variableAtParent: 'DATA FROM PARENT!'
  }
})
<script src="https://unpkg.com/vue@2.5.13/dist/vue.min.js"></script>

<div id="app">
  <p>At Parent: {{ variableAtParent }}<br>And is reactive (edit it) <input v-model="variableAtParent"></p>
  <child-comp :message="variableAtParent"></child-comp>
</div>


छोटा फिक्स: "<चाइल्ड-कॉम्प" के बजाय "<चाइल्ड" और
— वेरिएंटपैरेंट

यह केवल साधारण संपत्ति के साथ काम करेगा, वस्तु संदर्भों को अपडेट नहीं किया जाएगा। उदाहरण के लिए यदि आपके पास पैरेंट प्रॉपर्टी एरे है, और यह एरे को पेरेंट ऑब्जेक्ट में दूसरे एरे से बदल दिया गया है, तो बच्चा इसे नहीं देखेगा।
— स्टेन सोकोलोव

@StanSokolov बिल्कुल नहीं। मैं सरणियों के लिए काम करता हूं, देखें: jsfiddle.net/acdcjunior/q4mank05 । यदि आप सरणी प्रतिक्रियाशील नहीं हैं, तो आप संभवतः प्रतिक्रियात्मक समस्या का सामना कर रहे हैं। Vue.setयहाँ और अधिक प्रयोग करने का प्रयास करें: vuejs.org/v2/guide/reactivity.html#For-Arrays
— acdcjunior

यदि यह प्रतिक्रियाशील नहीं है तो क्या होगा? यकीन है कि यह संदर्भ के साथ प्रतिक्रियाशील था लगातार एक नए सरणी द्वारा प्रतिस्थापित किया गया। Vue बच्चों के लिए "संदर्भ परिवर्तन" का प्रचार नहीं करता है, केवल सरल तत्वों पर मूल्य परिवर्तन करता है। इसलिए अगर अभिभावकों के लिए सरणी का संदर्भ ओवरराइट किया गया था, तो बच्चे अभी भी पुराने संदर्भ को देखेंगे। पता नहीं होगा कि माता-पिता अब एक अलग वस्तु के साथ काम करते हैं।
— स्टेन सोकोलोव

@StanSokolov इसे देखें: jsfiddle.net/acdcjunior/ftmrne2h अभिभावक में सरणी को बदल दिया जाता है और बच्चा इसे देख / प्रतिक्रिया करता है (परीक्षण करने के लिए बटन पर क्लिक करें)। या आप कुछ और मतलब है? यदि ऐसा है, तो यदि आप इसे दिखाने के लिए
— फिडेल

15

मुझे लगता है कि मुद्दा यहाँ है:

<template id="newtemp" :name ="{{user.name}}">

जब आप अपने साथ हुए उपसर्ग को उपसर्ग के लिए :इंगित कर रहे हैं कि यह एक चर है, न कि एक स्ट्रिंग। तो अगर आप की जरूरत नहीं है {{}}चारों ओर user.name। प्रयत्न:

<template id="newtemp" :name ="user.name">

संपादित करें -----

उपरोक्त सत्य है, लेकिन यहां बड़ा मुद्दा यह है कि जब आप URL बदलते हैं और एक नए मार्ग पर जाते हैं, तो मूल घटक गायब हो जाता है। दूसरे घटक को मूल डेटा को संपादित करने के लिए, दूसरे घटक को पहले एक या एक ही घटक का एक बच्चा घटक होना चाहिए।


धन्यवाद जेफ मैंने {{}} को निकालने का प्रयास किया लेकिन मुझे अभी भी वही त्रुटियां हैं।
— प्रतिगामी

2

मुझे Vue में घटक स्कोप में पेरेंट डेटा पास करने का एक तरीका मिला है, मुझे लगता है कि यह थोड़ा हैक है लेकिन शायद यह आपकी मदद करेगा।

1) बाहरी वस्तु के रूप में Vue Instance में Reference Data (data : dataObj)

2) फिर चाइल्ड कंपोनेंट में डेटा रिटर्न फंक्शन में सिर्फ रिटर्न parentScope = dataObjऔर वॉयला। अब आप ऐसा नहीं कर सकते हैं {{ parentScope.prop }}और एक आकर्षण की तरह काम करेंगे।

शुभ लाभ!


Thats दोनों घटकों को एक साथ युग्मित करते हुए एक पेड़ और उसके नोड्स के लिए ठीक हो सकता है, लेकिन आम तौर पर इष्ट नहीं है। मैं इससे बचने की कोशिश करूंगा।
— दिसम्बर

1

उपर्युक्त प्रतिक्रियाएं अच्छी तरह से काम करती हैं लेकिन यदि आप 2 भाई घटकों के बीच डेटा पास करना चाहते हैं, तो इवेंट बस का भी उपयोग किया जा सकता है। इस ब्लॉग को देखें जो आपको बेहतर समझने में मदद करेगा।

2 घटकों के लिए प्रस्ताव: कंपा और CompB एक ही मूल और main.js होने के लिए मुख्य vue एप्लिकेशन की स्थापना के लिए। माता-पिता के घटक को शामिल किए बिना CompA से COMPB तक डेटा पास करने के लिए आप निम्न कार्य कर सकते हैं।

main.js फ़ाइल में, एक अलग वैश्विक Vue उदाहरण घोषित करें, जो इवेंट बस होगा।

export const bus = new Vue();

कॉम्पा में, जहां घटना उत्पन्न होती है: आपको घटना को बस में फेंकना होगा।

methods: {
      somethingHappened (){
          bus.$emit('changedSomething', 'new data');
      }
  }

अब कार्य उत्सर्जित घटना को सुनना है, इसलिए, CompB में, आप ऐसा सुन सकते हैं।

created (){
    bus.$on('changedSomething', (newData) => {
      console.log(newData);
    })
  }

लाभ:

  • कम और साफ कोड।
  • माता-पिता को 1 बच्चे से दूसरे के डेटा को पारित करने में शामिल नहीं होना चाहिए (जैसा कि बच्चों की संख्या बढ़ती है, इसे बनाए रखना मुश्किल हो जाएगा)
  • पब-उप दृष्टिकोण का पालन करता है।

0

मैं मुख्य गुणों का उपयोग कर पहुँचता हूँ $root।

Vue.component("example", { 
    template: `<div>$root.message</div>`
});
...
<example></example>

-2

एक वैश्विक JS वैरिएबल (ऑब्जेक्ट) का उपयोग घटकों के बीच डेटा पास करने के लिए किया जा सकता है। उदाहरण: Ammlogin.vue से Options.vue में डेटा पास करना। में Ammlogin.vue rspData सर्वर से प्रतिक्रिया के लिए सेट है। Options.vue में सर्वर से प्रतिक्रिया rspData के माध्यम से उपलब्ध कराई जाती है।

index.html:

<script>
    var rspData; // global - transfer data between components
</script>

Ammlogin.vue:

....    
export default {
data: function() {return vueData}, 
methods: {
    login: function(event){
        event.preventDefault(); // otherwise the page is submitted...
        vueData.errortxt = "";
        axios.post('http://vueamm...../actions.php', { action: this.$data.action, user: this.$data.user, password: this.$data.password})
            .then(function (response) {
                vueData.user = '';
                vueData.password = '';
                // activate v-link via JS click...
                // JSON.parse is not needed because it is already an object
                if (response.data.result === "ok") {
                    rspData = response.data; // set global rspData
                    document.getElementById("loginid").click();
                } else {
                    vueData.errortxt = "Felaktig avändare eller lösenord!"
                }
            })
            .catch(function (error) {
                // Wu oh! Something went wrong
                vueData.errortxt = error.message;
            });
    },
....

Options.vue:

<template>
<main-layout>
  <p>Alternativ</p>
  <p>Resultat: {{rspData.result}}</p>
  <p>Meddelande: {{rspData.data}}</p>
  <v-link href='/'>Logga ut</v-link>
</main-layout>
</template>
<script>
 import MainLayout from '../layouts/Main.vue'
 import VLink from '../components/VLink.vue'
 var optData = { rspData: rspData}; // rspData is global
 export default {
   data: function() {return optData},
   components: {
     MainLayout,
     VLink
   }
 }
</script>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.