[javascript] vue.js의 부모에서 자식 메서드에 액세스하는 방법

두 개의 중첩 구성 요소가 있습니다. 부모에서 자식 메서드에 액세스하는 적절한 방법은 무엇입니까?

this.$children[0].myMethod() 트릭을 수행하는 것처럼 보이지만 매우 추악하지 않습니까? 더 나은 방법이 될 수 있습니다.

<script>
import child from './my-child'

export default {
  components: {
   child
  },
  mounted () {
    this.$children[0].myMethod()
  }
}
</script>



답변

ref 사용할 수 있습니다 .

import ChildForm from './components/ChildForm'

new Vue({
  el: '#app',
  data: {
    item: {}
  },
  template: `
  <div>
     <ChildForm :item="item" ref="form" />
     <button type="submit" @click.prevent="submit">Post</button>
  </div>
  `,
  methods: {
    submit() {
      this.$refs.form.submit()
    }
  },
  components: { ChildForm },
})

타이트 커플 링이 마음에 들지 않으면 @Yosvel Quintero에 표시된대로 Event Bus 를 사용할 수 있습니다 . 다음은 버스를 소품으로 전달하여 이벤트 버스를 사용하는 또 다른 예입니다.

import ChildForm from './components/ChildForm'

new Vue({
  el: '#app',
  data: {
    item: {},
    bus: new Vue(),
  },
  template: `
  <div>
     <ChildForm :item="item" :bus="bus" ref="form" />
     <button type="submit" @click.prevent="submit">Post</button>
  </div>
  `,
  methods: {
    submit() {
      this.bus.$emit('submit')
    }
  },
  components: { ChildForm },
})

구성 요소 코드.

<template>
 ...
</template>

<script>
export default {
  name: 'NowForm',
  props: ['item', 'bus'],
  methods: {
    submit() {
        ...
    }
  },
  mounted() {
    this.bus.$on('submit', this.submit)
  },  
}
</script>

https://code.luasoftware.com/tutorials/vuejs/parent-call-child-component-method/


답변

VueJS의 부모-자녀 통신

루트 Vue 인스턴스가를 통해 모든 하위 항목에 this.$root액세스 할 수 있으므로 부모 구성 요소는 this.$children배열을 통해 자식 구성 요소에 액세스 할 수 있고 자식 구성 요소 는를 통해 부모 구성 요소에 액세스 할 수 있습니다. this.$parent첫 번째 본능은 이러한 구성 요소에 직접 액세스하는 것입니다.

VueJS 문서는 특히 두 가지 이유 때문에 이에 대해 경고합니다.

  • 부모와 자녀를 단단히 연결합니다 (반대의 경우도 마찬가지).
  • 부모의 상태는 자식 구성 요소에 의해 수정 될 수 있으므로 신뢰할 수 없습니다.

해결책은 Vue의 맞춤 이벤트 인터페이스를 사용하는 것입니다.

Vue에서 구현 한 이벤트 인터페이스를 사용하면 구성 요소 트리에서 위아래로 통신 할 수 있습니다. 사용자 지정 이벤트 인터페이스를 활용하면 다음 네 가지 방법에 액세스 할 수 있습니다.

  1. $on() -이벤트를 수신 할 Vue 인스턴스에서 리스너를 선언 할 수 있습니다.
  2. $emit() -동일한 인스턴스 (자체)에서 이벤트를 트리거 할 수 있습니다.

$on()및 사용 예 $emit():

const events = new Vue({}),
    parentComponent = new Vue({
      el: '#parent',
      ready() {
        events.$on('eventGreet', () => {
          this.parentMsg = `I heard the greeting event from Child component ${++this.counter} times..`;
        });
      },
      data: {
        parentMsg: 'I am listening for an event..',
        counter: 0
      }
    }),
    childComponent = new Vue({
      el: '#child',
      methods: {
      greet: function () {
        events.$emit('eventGreet');
        this.childMsg = `I am firing greeting event ${++this.counter} times..`;
      }
    },
    data: {
      childMsg: 'I am getting ready to fire an event.',
      counter: 0
    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.28/vue.min.js"></script>

<div id="parent">
  <h2>Parent Component</h2>
  <p>{{parentMsg}}</p>
</div>

<div id="child">
  <h2>Child Component</h2>
  <p>{{childMsg}}</p>
  <button v-on:click="greet">Greet</button>
</div>

원본 게시물에서 가져온 답변 : VueJS의 구성 요소 간 통신


답변

컨트롤 렌더가 v-if. 그래서 저는 더 간단한 방법을 사용하기로 결정했습니다.

아이디어는 배열을 큐로 사용하여 호출해야하는 메서드를 자식 구성 요소에 보내는 것입니다. 구성 요소가 마운트되면이 대기열을 처리합니다. 새로운 메서드를 실행하기 위해 큐를 감시합니다.

(Desmond Lua의 답변에서 일부 코드 대여)

상위 구성 요소 코드 :

import ChildComponent from './components/ChildComponent'

new Vue({
  el: '#app',
  data: {
    item: {},
    childMethodsQueue: [],
  },
  template: `
  <div>
     <ChildComponent :item="item" :methods-queue="childMethodsQueue" />
     <button type="submit" @click.prevent="submit">Post</button>
  </div>
  `,
  methods: {
    submit() {
      this.childMethodsQueue.push({name: ChildComponent.methods.save.name, params: {}})
    }
  },
  components: { ChildComponent },
})

이것은 ChildComponent의 코드입니다.

<template>
 ...
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    methodsQueue: { type: Array },
  },
  watch: {
    methodsQueue: function () {
      this.processMethodsQueue()
    },
  },
  mounted() {
    this.processMethodsQueue()
  },
  methods: {
    save() {
        console.log("Child saved...")
    },
    processMethodsQueue() {
      if (!this.methodsQueue) return
      let len = this.methodsQueue.length
      for (let i = 0; i < len; i++) {
        let method = this.methodsQueue.shift()
        this[method.name](method.params)
      }
    },
  },
}
</script>

그리고 processMethodsQueue믹스 인으로 이동 하는 것과 같은 개선의 여지가 많이 있습니다 .


답변

자식 구성 요소를 다른 자식 구성 요소와 통신하기 위해 다음을 사용하여 자식에서 메서드를 호출하는 부모 메서드를 만들었습니다.

this.$refs.childMethod()

그리고 다른 아이로부터 루트 메서드를 호출했습니다.

this.$root.theRootMethod()

그것은 나를 위해 일했습니다.


답변