자식 구성 요소의 vuejs 업데이트 부모 데이터


155

vuejs (2.0)로 게임을 시작합니다. 하나의 구성 요소가 포함 된 간단한 페이지를 작성했습니다. 이 페이지에는 데이터가있는 하나의 Vue 인스턴스가 있습니다. 해당 페이지에서 구성 요소를 html에 등록하고 추가했습니다. 구성 요소에는 하나가 input[type=text]있습니다. 그 값이 부모 (주 Vue 인스턴스)에 반영되기를 원합니다.

구성 요소의 상위 데이터를 올바르게 업데이트하려면 어떻게합니까? 부모로부터 바운드 소품을 전달하는 것은 좋지 않으며 콘솔에 경고가 발생합니다. 문서에 무언가가 있지만 작동하지 않습니다.


1
시도한 코드를 추가해도 작동하지 않습니다.
Saurabh 2016

답변:


181

Vue 2.0에서는 더 많은 이벤트 중심 아키텍처를 사용하기 위해 양방향 바인딩이 더 이상 사용되지 않습니다. 일반적으로 어린이는 소품을 변형해서는 안됩니다. 오히려, 그것은 $emit사건 이되어야 하고 부모가 그 사건에 응답하게 해야 합니다.

특정 경우에는로 맞춤 구성 요소를 사용할 수 있습니다 v-model. 이것은 양방향 바인딩에 가까운 것을 허용하는 특수 구문이지만 실제로 위에서 설명한 이벤트 중심 아키텍처의 약자입니다. 여기에서 읽을 수 있습니다-> https://vuejs.org/v2/guide/components.html#Form-Input-Components-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>

그렇기 때문에 아이의 소품에 가치를 부여 해야하는 이유와 아이가라는 이벤트를 $ emit 해야하는 이유 input입니다.


응답 주셔서 감사합니다. '입력'이벤트에 대한 문서를 확장하거나 더 잘 가리킬 수 있습니까? 내장 된 이벤트처럼 보입니다.
Gal Ziv 2016

나는 설명을 추가하고 문서에 대한 링크를보다 분명하게 만들었습니다.
asemahle

1
구성 요소 및 작성된 함수의 소품 "값"을 생략했지만 여전히 작동합니다. 왜 그것을 사용했는지 설명 할 수 있습니까?
xetra11

1
소품을 추가하지 않으면 undefined첫 번째 변경까지입니다. 내가 주석 처리 한이 바이올린을보십시오 props: ['value']. 초기 값이 얼마나주의 undefined대신에, hello: jsfiddle.net/asemahle/8Lrkfxj6을 . 첫 번째 변경 후 Vue는 구성 요소에 값 소품을 동적으로 추가하므로 작동합니다.
asemahle

나는 이것을 과거의 문서에서 바로 읽었습니다. 훌륭한 실례. 내가 할 수 있다면 +10!
클레이

121

로부터 문서 :

Vue.js에서 부모-자식 구성 요소 관계는 props down, events up으로 요약 될 수 있습니다. 부모는 소품을 통해 자식에게 데이터를 전달하고 자식은 이벤트를 통해 부모에게 메시지를 보냅니다. 그들이 다음에 어떻게 작동하는지 봅시다.

여기에 이미지 설명을 입력하십시오

소품을 전달하는 방법

다음은 소품을 자식 요소에 전달하는 코드입니다.

<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>

JS :

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
함수 "증가"가 부모 구성 요소에 있고 자식 구성 요소에서 트리거하려면 어떻게해야합니까?
Hamzaouiii

해키 카피 붙여 넣기로 여러 번 사용해 왔지만 개념을 파악하는 데 도움이되는 전단 순간
Yordan Georgiev

1
그 그래픽을 인쇄해서 내 머리에 붙입니다. 고마워!
domih

1
이 예제에서 루트 컴포넌트에 이벤트 리스너가 정의되어 있지 않아야합니까? ```mount () {this.on ( 'increment', () => {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

위의 사항에 대한 이벤트 생성 및 v 모델 답변에 동의합니다. 그러나 여러 양식 요소가있는 구성 요소에 대해 찾은 내용을 Google에 반환 된 첫 번째 기사 중 하나 인 것처럼 부모에게 다시 내보내려는 내용을 게시한다고 생각했습니다.

나는 질문이 단일 입력을 지정한다는 것을 알고 있지만 이것은 가장 일치하는 것처럼 보였고 유사한 vue 구성 요소로 시간을 절약 할 수 있습니다. 또한 아무도 .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>

객체를 통해 한 번에 여러 개를 동기화 할 수도 있습니다. 여기 에서 설명서를 확인 하십시오


이것이 내가 찾던 것입니다. 고마워
Thomas

이것은 2020 년 기준으로 가장 최신의 최신 솔루션입니다. 대단히 감사합니다!
Marcelo

6

더 간단한 방법은 사용입니다 this.$emit

아버지. 뷰

<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/components.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) Child Compnent : 하위 컴포넌트에서 이와 같이 사용할 수 있습니다.

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

2) Parrent Compnenet : Parrent Component 태그에서 다음과 같이 변수를받습니다. 이것은 부모 구성 요소 태그에서 해당 하위 구성 요소 데이터를 수신하는 코드입니다

@send="newformValue"

0

또 다른 방법은 React에서 수행하는 방식과 유사하게 부모에서 소품으로 하위 집합에 대한 setter의 참조를 전달하는 것입니다. updateValue부모에게 값을 업데이트 하는 메소드가 있다고 가정하면 다음 과 같이 자식 구성 요소를 인스턴스화 할 수 <child :updateValue="updateValue"></child>있습니다. 그런 다음 자식에는 해당 prop : props: {updateValue: Function}이 있고 템플릿에서 입력이 변경되면 메서드를 호출합니다 <input @input="updateValue($event.target.value)">.


0

왜 그런지 모르겠지만, 난 그냥 성공적으로 객체로 데이터를 사용하여 부모 데이터를 업데이트 :setcomputed

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

그의 예제는 제출 버튼에서 입력 값을 부모에게 전달하는 방법을 알려줍니다.

먼저 eventBus를 새로운 Vue로 정의하십시오.

//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)"

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.