2017-12-18 21 views
0

중첩 구성 요소가 있고 하위 구성 요소가 주 인스턴스에서 매개 변수를 받아야하지만 문제는 매개 변수를 두 번 가져와 이벤트를 호출해야한다는 것입니다.두 번째 호출 후 Vue2 이벤트 버스 작동

index.html을

<div id="app"> 
    <button @click="displayComponent">Display</button><br/><hr/> 
    {{ message }} 

    <mycomponent v-if="showComponent" @hide="hideComponents"></mycomponent> 
</div> 

code.js

window.bus = new Vue(); 

Vue.component('mycomponent', { 
    template: ` 
     <div> 
      <h3>Im the parent component</h3> 
      <childcomponent></childcomponent> 
      <button @click="$emit('hide')">Hide components</button> 
     </div> 
    ` 
}); 

Vue.component('childcomponent', { 
    template:` 
     <div> 
      <h4>Im the child component</h4> 
      <p>{{ data }}</p> 
     </div> 
    `, 

    data() { 
     return { 
      text: 'Nothing loaded' 
     }; 
    }, 

    methods: { 
     test() { 
      alert('hello'); 
     }, 

     getData(x) { 
      this.text = x; 
     } 
    }, 

    created(){ 
     bus.$on('extraCall', data => { 
      this.getData(data); 
      this.test(); 
     }); 
    } 
}); 

const app = new Vue({ 
    el: '#app', 

    data: { 
     message: 'hello world!', 
     showComponent: false 
    }, 

    methods: { 
     displayComponent() {   
      bus.$emit('extraCall', 'this is some extra text'); 
      this.showComponent = true; 
     }, 

     hideComponents() { 
      this.showComponent=false; 
     } 
    } 
}); 

디스플레이 버튼을 클릭 한 후 하위 구성 요소 내부의 텍스트 값은 기본값으로 설정되어가 함께 bus.$emit를 발생 일부 텍스트를 매개 변수로 사용하는 extraCall 이벤트의 경우 텍스트 값을 업데이트해야하며 표시 버튼을 두 번째 클릭 한 후에 만 ​​발생합니다.

무엇이 누락 되었습니까? 때문에 표시 단추를 클릭 할 때

답변

1

<mycomponent> (및 해당 자식 <childcomponent>)이 인스턴스화되지 않습니다.

먼저 클릭 :

  1. extraCall 버스에 방출되지만 무시되도록 청취자는 이벤트가 없습니다.
  2. <mycomponent>showComponent을 true로 설정 한 후에 인스턴스화됩니다.
  3. <mycomponent>created 후크에 extraCall 이벤트에 대한 수신기를 등록합니다.

번째 클릭

  1. extraCall 버스에서 출사되고 <mycomponent>는 그것을 처리한다.
당신은 bus.$emit()this.showComponent = true 라인 <mycomponent> 이벤트가 방출되는 전에 의 인스턴스를 가져옵니다 그래서 교환되어야하지만 뷰는 다음 microtask 때까지 구성 요소의 생성을 연기 때문에 여전히 작동하지 않을 생각

보기가 갱신됩니다.

이 작동 할 수 있습니다 :

displayComponent() { 
    this.showComponent = true; 

    // Wait for child component to be instantiated 
    this.$nextTick(() => { 
    bus.$emit('extraCall', 'this is some extra text'); 
    }); 
} 

을 위의 코드는 당신을 위해 작동하는 경우, 나는 아직도 정말 생각하지 않는 것이 좋습니다. 이벤트를 보내기 전에 하위 구성 요소의 생성을 설명 할 필요는 없습니다. 구성 요소를 함께 연결합니다. 데이터를 다른 방식으로 공유하고 다른 SO 질문을 확인하여 구성 요소간에 데이터를 공유하는 가장 좋은 방법을 찾아야합니다.

+0

좋습니다. 정상적으로 작동하지 않지만 더 나은 해결책이 있어야합니다. 그러나 이것이 해결책으로 투표하는 주요한 문제를 해결했기 때문에 더 좋은 사람이 여기에 게시 될 것입니다. 고마워요! – deadPoet

+0

글쎄, 당신이 정말로 좋고 협조적이기 때문에, 나는 이것과 똑같은 일을 해냈다. 나는 그 일을 얼마 전 해냈다.하지만 지금은 그렇지 않다. 내가 찾은 유일한 차이점은 html 파일에있다. 조건 v-show 대신에 구성 요소를 표시하는 경우, v-show 일 때, 내가 그것을 변경하면, 그냥 작동합니다 ... 이것을 사용하여 부차적 인 피해를 줄 수 있습니까? ... AFAIK v-show는로드하는 데 더 많은 시간이 걸리지 만 바로 표시됩니다. v-if는 호출 될 때마다 구성 요소를 만듭니다. – deadPoet

+1

'v-show'는 요소의 스타일 만 토글합니다. 'v-show'가 false이면, 컴포넌트는 여전히 생성됩니다. 스타일 때문에 숨겨져 있습니다 (dev 툴에서 볼 수 있습니다). 'v-if'는 실제로 요소를 파괴/생성합니다. 여기에'v-if' 대신에'v-show'를 사용하면 원래 코드와 함께 작동합니다. 'v-if'와'v-show' 사이를 결정하려면 (1) 항상 생성 된 요소가 필요합니까? (2) DOM에서 숨겨진 요소가': nth-child' CSS 선택자에 영향을 줍니까? (3)'v-show '로 요소를 유지하면 더 많은 메모리가 사용됩니다. –