vuejs बच्चे के घटक से मूल डेटा अपडेट करते हैं


155

मैं vuejs (2.0) के साथ खेलना शुरू कर रहा हूं। मैंने इसमें एक घटक के साथ एक सरल पृष्ठ बनाया। पृष्ठ में डेटा के साथ एक Vue उदाहरण है। उस पृष्ठ पर मैंने पंजीकृत किया और HTML में घटक जोड़ा। घटक के पास एक है input[type=text]। मैं उस मूल्य को मूल (मुख्य Vue उदाहरण) पर प्रतिबिंबित करना चाहता हूं।

मैं घटक के मूल डेटा को सही तरीके से कैसे अपडेट करूं? माता-पिता से एक बाउंड प्रोप पास करना अच्छा नहीं है और कंसोल के लिए कुछ चेतावनी फेंकता है। उनके डॉक में कुछ है लेकिन यह काम नहीं कर रहा है।


1
क्या आप अपने द्वारा कोशिश किए गए कोड को जोड़ सकते हैं, जो काम नहीं कर रहा है।
सौरभ

जवाबों:


181

अधिक-चालित वास्तुकला का उपयोग करने के पक्ष में Vue 2.0 में दो-तरफ़ा बंधन को हटा दिया गया है। सामान्य तौर पर, एक बच्चे को अपने प्रॉप्स को म्यूट नहीं करना चाहिए। इसके बजाय, इसे $emitघटनाओं को करना चाहिए और माता-पिता को उन घटनाओं का जवाब देना चाहिए ।

अपने विशिष्ट मामले में, आप कस्टम घटक का उपयोग कर सकते हैं v-model। यह एक विशेष वाक्यविन्यास है जो दो-तरफ़ा बंधन के करीब कुछ के लिए अनुमति देता है, लेकिन वास्तव में ऊपर वर्णित घटना-संचालित वास्तुकला के लिए एक आशुलिपि है। आप इसके बारे में यहाँ पढ़ सकते हैं -> https://vuejs.org/v2/guide/compords.html#Form-Input-Compords-using-Custom-Events

यहाँ एक सरल उदाहरण दिया गया है:

Vue.component('child', {
  template: '#child',
  
  //The child has a prop named 'value'. v-model will automatically bind to this prop
  props: ['value'],
  methods: {
    updateValue: function (value) {
      this.$emit('input', value);
    }
  }
});

new Vue({
  el: '#app',
  data: {
    parentValue: 'hello'
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{parentValue}}</p>
  <child v-model="parentValue"></child>
</div>

<template id="child">
   <input type="text" v-bind:value="value" v-on:input="updateValue($event.target.value)">
</template>


डॉक्स बताता है कि

<custom-input v-bind:value="something" v-on:input="something = arguments[0]"></custom-input>

के बराबर है

<custom-input v-model="something"></custom-input>

इसीलिए बच्चे पर होने वाले प्रॉप को वैल्यू का नाम देना पड़ता है, और बच्चे को नाम की घटना के लिए $ ईमित्र की जरूरत क्यों पड़ती है input


प्रतिक्रिया के लिए पहला धन्यवाद। क्या आप 'इनपुट' ईवेंट के बारे में दस्तावेजों का विस्तार या बेहतर बिंदु बता सकते हैं? यह एक निर्मित घटना की तरह लगता है।
गाल ज़िव

मैंने एक स्पष्टीकरण जोड़ा है, और प्रलेखन के लिंक को अधिक स्पष्ट किया है।
17

1
मैंने घटक और बनाए गए फ़ंक्शन के लिए प्रोप "मूल्य" को छोड़ दिया और यह अभी भी काम करता है। क्या आप बता सकते हैं कि आपने इसका उपयोग क्यों किया?
xetra11

1
यदि आप प्रोप नहीं जोड़ते हैं, तो यह undefinedपहले बदलाव तक होगा । इस फिडेल को देखें जहां मैंने टिप्पणी की है props: ['value']। ध्यान दें कि undefinedइसके बजाय प्रारंभिक मूल्य कैसे है hello: jsfiddle.net/asemahle/8Lrkfxj6 । पहले परिवर्तन के बाद, Vue गतिशील रूप से घटक के लिए एक वैल्यू प्रोप जोड़ता है, इसलिए यह काम करता है।
asemahle

मैंने इसे डॉक्स में सही पढ़ा है। महान काम करने का उदाहरण। +10 अगर मैं कर सका!
मिट्टी

121

से प्रलेखन :

Vue.js में, माता-पिता-बच्चे घटक संबंध को संक्षेप में, नीचे घटनाओं के रूप में संक्षेपित किया जा सकता है। माता-पिता प्रॉपर के माध्यम से बच्चे को डेटा पास करते हैं, और बच्चा घटनाओं के माध्यम से माता-पिता को संदेश भेजता है। देखते हैं कि वे आगे कैसे काम करते हैं।

यहाँ छवि विवरण दर्ज करें

कैसे पास करें

निम्नलिखित एक बाल तत्व के लिए सहारा पास करने के लिए कोड है:

<div>
  <input v-model="parentMsg">
  <br>
  <child v-bind:my-message="parentMsg"></child>
</div>

ईवेंट का उत्सर्जन कैसे करें

HTML:

<div id="counter-event-example">
  <p>{{ total }}</p>
  <button-counter v-on:increment="incrementTotal"></button-counter>
  <button-counter v-on:increment="incrementTotal"></button-counter>
</div>

जे एस:

Vue.component('button-counter', {
  template: '<button v-on:click="increment">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    increment: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})

5
क्या होगा अगर समारोह componentincrement´was मूल घटक में और मैं इसे बच्चे घटक से ट्रिगर करना चाहता था?
हमजाऊई

इस अवधारणा को समझने का क्षण, यद्यपि इसे कई बार हैकी कॉपी पेस्ट द्वारा उपयोग किया गया है ...
योर्डन जॉर्जीव

1
मैं उस ग्राफिक को प्रिंट करूंगा और उसे अपने सिर पर चिपका लूंगा। धन्यवाद!
डोमिह

1
इस उदाहरण में, क्या हमें इवेंट कंपोनेंट को रूट कंपोनेंट में परिभाषित नहीं करना चाहिए? कुछ इस तरह: `` `घुड़सवार () {this.on ('वेतन वृद्धि', () => {this.incrementTotal ();}); } `` `
jmk2142

94

बच्चे के घटक में:

this.$emit('eventname', this.variable)

मूल घटक में:

<component @eventname="updateparent"></component>

methods: {
    updateparent(variable) {
        this.parentvariable = variable
    }
}

3
मेरा दिमाग बस इस उदाहरण से उड़ा है। आपको पता नहीं है कि मैं यहाँ आने से पहले कितने ट्यूटोरियल से
गुजरा था

18

बाल घटक

this.$emit('event_name')पैरेंट घटक को ईवेंट भेजने के लिए उपयोग करें ।

यहाँ छवि विवरण दर्ज करें

जनक घटक

मूल घटक में उस घटना को सुनने के लिए, हम करते हैं v-on:event_nameऔर एक विधि ( ex. handleChange) जिसे हम उस घटना पर निष्पादित करना चाहते हैं

यहाँ छवि विवरण दर्ज करें

किया हुआ :)


13

मैं उन लोगों के लिए ईवेंट एमिटिंग और वी-मॉडल उत्तरों से सहमत हूं। हालाँकि, मुझे लगा कि मैं पोस्ट करूँगा कि मुझे कई फॉर्म तत्वों वाले घटकों के बारे में क्या मिला जो अपने माता-पिता को वापस भेजना चाहते हैं क्योंकि ऐसा लगता है कि यह Google द्वारा पहले लेख में से एक है।

मुझे पता है कि प्रश्न एक एकल इनपुट निर्दिष्ट करता है, लेकिन यह निकटतम मैच लगता था और हो सकता है कि कुछ इसी तरह के घटकों के साथ लोगों को बचाए। इसके अलावा, किसी ने भी .syncसंशोधक का उल्लेख नहीं किया है।

जहाँ तक मुझे पता है, v-modelसमाधान केवल उनके माता-पिता को लौटाने वाले इनपुट के अनुकूल है। मुझे इसकी तलाश में थोड़ा समय लग गया लेकिन Vue (2.3.0) प्रलेखन दिखाता है कि घटक में भेजे गए कई प्रॉप्स को वापस माता-पिता में कैसे सिंक किया जाए (पाठ्यक्रम के उत्सर्जन के माध्यम से)।

इसे उचित रूप से .syncसंशोधक कहा जाता है ।

यहाँ दस्तावेज क्या कहते हैं:

कुछ मामलों में, हमें एक प्रोप के लिए "टू-वे बाइंडिंग" की आवश्यकता हो सकती है। दुर्भाग्य से, सच्चा दो-तरफ़ा बंधन रखरखाव के मुद्दे पैदा कर सकता है, क्योंकि बच्चे के घटक माता-पिता और बच्चे दोनों में स्पष्ट होने वाले उत्परिवर्तन के स्रोत के बिना माता-पिता को उत्परिवर्तित कर सकते हैं।

इसीलिए, इसके बजाय, हम ईवेंट्स को ईवेंट में बदलने की सलाह देते हैं update:myPropName। उदाहरण के लिए, एक titleप्रोप के साथ काल्पनिक घटक में , हम एक नया मान निर्दिष्ट करने के इरादे से संवाद कर सकते हैं:

this.$emit('update:title', newTitle)

तब माता-पिता उस घटना को सुन सकते हैं और यदि चाहें तो एक स्थानीय डेटा संपत्ति को अपडेट कर सकते हैं। उदाहरण के लिए:

<text-document   
 v-bind:title="doc.title"  
 v-on:update:title="doc.title = $event"
></text-document>

सुविधा के लिए, हम .sync संशोधक के साथ इस पैटर्न के लिए एक आशुलिपि प्रदान करते हैं:

<text-document v-bind:title.sync="doc.title"></text-document>

आप किसी ऑब्जेक्ट के माध्यम से भेजकर एक बार में कई सिंक कर सकते हैं। की जाँच करें यहाँ प्रलेखन


यह वही है जिसे मैं देख रहा था। बहुत बहुत धन्यवाद।
थॉमस

यह 2020 तक के लिए सबसे अच्छा और सबसे अद्यतित समाधान है। बहुत बहुत धन्यवाद!
मार्सेलो

6

जिस तरह से अधिक सरल उपयोग है this.$emit

Father.vue

<template>
  <div>
    <h1>{{ message }}</h1>
    <child v-on:listenerChild="listenerChild"/>
  </div>
</template>

<script>
import Child from "./Child";
export default {
  name: "Father",
  data() {
    return {
      message: "Where are you, my Child?"
    };
  },
  components: {
    Child
  },
  methods: {
    listenerChild(reply) {
      this.message = reply;
    }
  }
};
</script>

Child.vue

<template>
  <div>
    <button @click="replyDaddy">Reply Daddy</button>
  </div>
</template>

<script>
export default {
  name: "Child",
  methods: {
    replyDaddy() {
      this.$emit("listenerChild", "I'm here my Daddy!");
    }
  }
};
</script>

मेरा पूरा उदाहरण: https://codesandbox.io/s/update-parent-property-ufj4b


5

ऑब्जेक्ट या एरे के रूप में प्रॉपर पास करना भी संभव है। इस मामले में डेटा दो तरह से बाँधा जाएगा:

(यह विषय के अंत में नोट किया गया है: https://vuejs.org/v2/guide/compenders.html#One-Way-Data-Flow )

Vue.component('child', {
  template: '#child',
  props: {post: Object},
  methods: {
    updateValue: function () {
      this.$emit('changed');
    }
  }
});

new Vue({
  el: '#app',
  data: {
    post: {msg: 'hello'},
    changed: false
  },
  methods: {
    saveChanges() {
        this.changed = true;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{post.msg}}</p>
  <p v-if="changed == true">Parent msg: Data been changed - received signal from child!</p>
  <child :post="post" v-on:changed="saveChanges"></child>
</div>

<template id="child">
   <input type="text" v-model="post.msg" v-on:input="updateValue()">
</template>



0

1) बाल संपीड़ित: आप इस तरह से उपयोग कर सकते हैं बाल घटक इस तरह से लिखें: यह है। विफ़ल्यू को कुछ उत्पाद घटक के लिए भेजना है

this.$emit('send',this.formValue)

2) पैरेंट कॉम्पेनेट: और पैरेंट कंपोनेंट टैग में इस तरह वेरिएबल भेजते हैं: और यह वह कोड होता है जो उस बच्चे को पेरेंट कंपोनेंट टैग में डेटा कंपेयर करने के लिए होता है

@send="newformValue"

0

दूसरा तरीका यह है कि माता-पिता से अपने घटक का एक संदर्भ बाल घटक के लिए एक प्रस्ताव के रूप में पारित करें, जैसा कि वे इसे रिएक्ट में करते हैं। कहते हैं, आप एक विधि है updateValueमान अपडेट माता पिता पर, आप तो जैसे बच्चे घटक का दृष्टांत सकता है: <child :updateValue="updateValue"></child>। फिर बच्चे पर आपके पास एक समान प्रोप होगा: props: {updateValue: Function}और इनपुट बदलने पर टेम्पलेट कॉल विधि में <input @input="updateValue($event.target.value)">:।


0

मुझे पता नहीं क्यों, लेकिन मैंने ऑब्जेक्ट के रूप में डेटा का उपयोग करने के साथ बस सफलतापूर्वक पैरेंट डेटा अपडेट किया है, :set औरcomputed

Parent.vue

<!-- check inventory status - component -->
    <CheckInventory :inventory="inventory"></CheckInventory>

data() {
            return {
                inventory: {
                    status: null
                },
            }
        },

Child.vue

<div :set="checkInventory">

props: ['inventory'],

computed: {
            checkInventory() {

                this.inventory.status = "Out of stock";
                return this.inventory.status;

            },
        }

0

उसका उदाहरण आपको बताएगा कि सबमिट बटन पर अभिभावक को इनपुट वैल्यू कैसे पास करनी है।

पहले घटना को नए वीयू के रूप में परिभाषित करें।

//main.js
import Vue from 'vue';
export const eventBus = new Vue();

Pass your input value via Emit.
//Sender Page
import { eventBus } from "../main";
methods: {
//passing data via eventbus
    resetSegmentbtn: function(InputValue) {
        eventBus.$emit("resetAllSegment", InputValue);
    }
}

//Receiver Page
import { eventBus } from "../main";

created() {
     eventBus.$on("resetAllSegment", data => {
         console.log(data);//fetching data
    });
}

0

मुझे लगता है कि यह चाल चलेगा:

@change="$emit(variable)"

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.