Vue js 2를 사용하여 구성 요소 하위 구성 요소 체인에서 이벤트를 버블링하려면 어떻게 해야 합니까?
vue 어플리케이션을 사용하고 있는 경우:
컴포넌트-자녀로 이루어진 컴포넌트-부모 컴포넌트
inside component-parent 버튼이 있습니다.누군가 버튼을 클릭하면 vue에 의해 처리되어 다른 컴포넌트로 전달되기 위해 이벤트를 내보내고 싶습니다.
지금까지 한 일:
var vm = new Vue({
el: '#app',
methods: {
itemSelectedListener: function(item){
console.log('itemSelectedListener', item);
}
}
});
Vue.component('component-child', {
template: ' <span v-on:click="chooseItem(pty )" >Button </span>',
methods: {
chooseItem: function(pty){
console.log(pty);
this.$emit('itemSelected', {
'priority' : pty
});
}
}
});
Vue.component('component-parent', {
template: '<component-child v-for="q in items" ></component-child>'
});
HTML:
<component-parent v-on:itemSelected="itemSelectedListener" ></component-parent>
내 손에 닿다console.log(pty);
라인이지만 그런 것 같다this.$emit('itemSelected'
통과할 수 없음:
console.log('itemSelectedListener', item); // this is not going to be called...
힌트?
이벤트를 자녀->부모->Vue-instance에서 버블링해야 합니까?(나도 시도해봤지만 성공하지 못했어)
고객님께 문제가 하나 있습니다.component-parent
여러 개의 하위 구성 요소를 렌더링하려고 할 때 템플릿이 사용됩니다.Vue는 일반적으로 구성 요소 내부에 단일 루트 div가 필요하므로 div 또는 다른 태그로 래핑해야 합니다.
<div>
<component-child v-for="q in items"></component-child>
</div>
두 번째 포인트는 하위 컴포넌트에서 이벤트를 2레벨 아래로 내보내고 루트로 재생하는 것입니다.
Root //but you listen to the event up here 1 level above
Component 1 //you should listen to the event here
Component 2 //your try to emit it from here
여기에는 두 가지 옵션이 있습니다.어느쪽인가에서 방출하다component-child
에서 그 사건을 듣다component-parent
그 이벤트를 위로 전파합니다.https://jsfiddle.net/bjqwh74t/29/ 를 조작합니다.
두 번째 옵션은 이른바 글로벌 등록입니다.bus
이 인스턴스는 부모 구성 요소가 아닌 구성 요소 간에 통신하려는 경우에 사용할 수 있는 빈 vue 인스턴스입니다.https://jsfiddle.net/bjqwh74t/30/ 를 조작합니다.
일반적으로 상위 컴포넌트와 하위 컴포넌트 사이에서 이벤트를 직접 사용하여 하위 컴포넌트에서 내보내고 상위 컴포넌트에서 이벤트를 청취합니다.v-on:event-name="handler"
그러나 성분 간의 수준이 더 높은 경우에는 두 번째 방법을 사용합니다.
첫 번째 케이스의 Doc 링크:https://vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events
두 번째 케이스의 Doc 링크: 。https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
PS: 이벤트 이름에 kebab-case를 사용하는 것을 선호합니다.즉, 다음과 같이 씁니다.-
대문자 대신.대문자로 쓰는 것은 사건이 근원적으로 잡히지 않는 이상한 상황을 초래할 수 있습니다.
브라우저의 이벤트 API를 사용할 수 있습니다.Vue에 내장된 것보다 조금 더 많은 스크립트가 필요하지만 이러한 버블링 문제를 해결할 수 있습니다(또한 승인된 답변과 같은 코드 양입니다).
하위 구성 요소:
this.$el.dispatchEvent(new CustomEvent('itemSelected', { detail: { 'priority' : pty }, bubbles: true, composed: true });
컴포넌트의 , 「」의mounted
다음 중 하나:
mounted() {
this.$el.addEventListener('itemSelected', e => console.log('itemSelectedListener', e.detail));
}
조금 늦었지만 방법은 다음과 같습니다.
component-child:
this.$root.$emit('foobar',{...});
컴포넌트 부모:
this.$root.$on('foobar')
'자성분'이라고 쓰면 .$emit
를 $root
음음음같 뭇매하다
v-on:click="$root.$emit('hamburger-click')"
다음 : "합니다.mounted
라이프 사이클 훅은 다음과 같습니다.
export default {
<snip...>
mounted: function() {
this.$root.$on('hamburger-click', function() {
console.log(`Hamburger clicked!`);
});
}
}
아무도 이벤트 버스 컴포넌트를 사용할 것을 제안하지 않았다니 조금 놀랐습니다.고도로 분리된 시스템에서는 공유 이벤트버스가 있으며, 이를 사용하여 여러 개의 분리된 컴포넌트를 pub/sub 스타일로 링크하는 것이 매우 일반적인 패턴입니다.
//eventbus.js
import Vue from 'vue'
export const EventBus = new Vue()
이벤트만 있으면 어디서든 쉽게 게시할 수 있습니다.
// component1.js
import { EventBus } from '@/services/eventbus'
...
EventBus.$emit('do-the-things')
그리고 다른 곳에서 들어보십시오.
// component2.js
import { EventBus } from '@/services/eventbus'
...
EventBus.$on('do-the-things', this.doAllTheThings)
두 컴포넌트는 서로에 대해 아무것도 모르기 때문에 이벤트가 발생한 방법이나 이유는 신경 쓸 필요가 없습니다.
이 접근법에는 잠재적으로 바람직하지 않은 부작용이 있다.이벤트 이름은 앱을 혼동하지 않도록 글로벌하게 고유해야 합니다.또한 보다 정교한 작업을 수행하지 않는 한 모든 이벤트를 단일 개체를 통해 채널링할 수도 있습니다.자신의 앱 소스에서 비용/편익 분석을 수행하여 자신에게 적합한지 확인할 수 있습니다.
버블링을 위한 커스텀 디렉티브를 생성하여 자 컴포넌트에서 사용합니다.
지시문 예시:
// Add this to main.ts when initializing Vue
Vue.directive('bubble', {
bind(el, { arg }, {context, componentInstance}) {
if (!componentInstance || !context || !arg) {
return;
}
// bubble the event to the parent
componentInstance.$on(v, context.$emit.bind(context, arg));
}
});
하위 구성 요소는 이 명령을 사용하여 상위 구성 요소를 통해 내보낼 수 있습니다(kabob 대소문자 및 이벤트 줄임말로 전환했습니다).
<!-- template for component-parent -->
<component-child v-bubble:item-selected v-for="q in items"></component-child>
<!-- usage of component-parent -->
<component-parent @:item-selected="itemSelectedListener"></component-parent>
아래 제 풀바인드 지시도 포함해서요.여러 이벤트를 버블링할 수 있습니다.
<!--------------------
* A few examples
--------------------->
<!-- bubble single event -->
<child v-bubble:click/>
<child v-bubble:_.click/>
<child v-bubble="'click'"/>
<child v-bubble:any-costume-event-will-work/>
<!-- bubble: click, focus, blur -->
<child v-bubble:_.click.focus.blur/>
<child v-bubble="'click, focus, blur'"/>
<!-- prefixed bubbling: click, focus, blur as child-click, child-focus, child-blur -->
<child v-bubble:child.click.focus.blur/>
<child v-bubble:child="'click, focus, blur'"/>
Vue.directive('bubble', {
bind(el, { value, arg: prefix = '', modifiers }, {context, componentInstance}) {
const events = value && value.trim() ? value.split(',') : Object.keys(modifiers);
if (!events.length && prefix) {
events.push(prefix);
prefix = '';
} else if(prefix) {
prefix = prefix === '_' ? '' : prefix += '-';
}
if (!componentInstance || !context || !events.length) {
return;
}
events.forEach((v: string) => {
v = v.trim();
const eventName = `${prefix}${v}`;
const bubble = context.$emit.bind(context, eventName);
componentInstance.$on(v, bubble);
});
}
});
언급URL : https://stackoverflow.com/questions/42029150/how-to-bubble-events-on-a-component-subcomponent-chain-with-vue-js-2
'source' 카테고리의 다른 글
세트에서 요소 가져오기 (0) | 2022.08.16 |
---|---|
왜 Double일까요?음수가 아닌 MIN_VALUE (0) | 2022.08.16 |
vuex를 사용하여 API에서 데이터를 가져오는 모범 사례 (0) | 2022.08.16 |
Java에서 BigDecimal 변수 == 0인지 확인하는 방법 (0) | 2022.08.16 |
루프 내에는 현재 루프되어 있는 일치를 취득하여 특정 이름의 참가자를 반환하는 함수가 있습니다.중복을 방지하는 방법 (0) | 2022.08.16 |