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처럼 이벤트 버스를 이용할 수 있습니다.아래는 버스를 타고 지나가는 이벤트 버스를 소품으로 사용하는 또 다른 예입니다.
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/
Vue 2.7 및 Vue 3.2.x의 경우
<!-- Parent -->
<script setup>
import { ref, onMounted } from 'vue'
import ChildComponent from './components/ChildComponent.vue'
const childComponentRef = ref()
onMounted(() => {
childComponentRef.value.doSomething()
})
</script>
<template>
<ChildComponent ref="childComponentRef" />
</template>
스크립트 설정
<!-- Child -->
<script setup>
const doSomething = () => {
console.log('Im batman')
}
defineExpose({
doSomething
})
</script>
셋업기능
<!-- Child -->
<script>
import { defineComponent } from 'vue'
export default defineComponent({
setup(props, context) {
const doSomething = () => {
console.log('Im batman')
}
context.expose({ doSomething })
}
})
</script>
참고: 이런 행동은 피하고 컴포지트를 사용해야 합니다.구성 요소(타사 플러그인 등)를 제어할 수 없는 경우.
제안된 솔루션은 Vue 2용이지만, Vue 3 Composition API 솔루션을 찾는 경우 마이그레이션할 때 다음을 수행할 수 있습니다.
"doSomething" 메서드가 있는 템플릿의 자식 구성 요소:
<div class="form">
<child-component ref="childComponentRef" />
</div>
Vue 2 사용:
this.$refs.childComponentRef.doSomething( );
Vue 3 Composition Api 사용:
setup( )
{
const childComponentRef = ref( );
childComponentRef.value.doSomething( )
return {
childComponentRef
}
}
VueJS에서의 부모-자녀 통신
는 를 모든 수 .this.$root 요소는 , 를 요소에 수 .this.$children배열, 자식 구성 요소는 다음을 통해 부모 구성 요소에 액세스할 수 있습니다.this.$parent은 이 .
VueJS 설명서는 다음과 같은 두 가지 매우 좋은 이유로 이에 대해 경고합니다.
- 부모와 자녀를 긴밀하게 연결합니다(그리고 그 반대도 마찬가지입니다).
- 부모의 상태는 자식 구성 요소로 수정할 수 있기 때문에 의존할 수 없습니다.
해결책은 뷰의 사용자 지정 이벤트 인터페이스를 사용하는 것입니다.
Vue에서 구현한 이벤트 인터페이스를 사용하면 구성 요소 트리를 위아래로 통신할 수 있습니다.사용자 지정 이벤트 인터페이스를 활용하면 다음과 같은 네 가지 방법에 액세스할 수 있습니다.
$on()을 다)를 Vue 할 수 .$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좀 더 그래서 좀 더 간단한 방법으로 진행하기로 했습니다.
이 아이디어는 배열을 큐로 사용하여 자식 구성 요소에 호출해야 하는 메서드를 전송하는 것입니다.구성 요소가 마운트되면 이 대기열을 처리합니다.이것은 새로운 메소드를 실행하기 위해 대기열을 감시합니다.
(데스몬드 루아의 대답에서 코드를 빌리고 있음)
상위구성요소코드:
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 },
})
하위 구성요소 코드입니다.
<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...에 섞이게 됩니다.
mohgaderi의 답변이 마음에 드는데, 몇 가지 문제가 생겨서 그의 샘플 코드를 사용해서 제가 수정해야 할 부분을 보여드리겠습니다. (제 프로젝트에서는 Vue 3와 Options API를 사용하고 있습니다.)
Mohgaderi의 부모 구성 요소 코드와 내 변경 사항에 대한 참고 사항:
import ChildComponent from './components/ChildComponent'
new Vue({
el: '#app',
data: {
item: {},
childMethodsQueue: [],
},
// Note: In the template below, I added @child-methods-finished="childMethodsFinished"
// as an event listener, so that we can reset the childMethodsQueue array to
// empty once the methods are finished.
// If you don't reset it, then the methods stay in there and cause problems.
template: `
<div>
<ChildComponent :item="item"
:methods-queue="childMethodsQueue"
@child-methods-finished="childMethodsFinished" />
<button type="submit" @click.prevent="submit">Post</button>
</div>
`,
methods: {
submit() {
this.childMethodsQueue.push({
name: ChildComponent.methods.save.name,
params: {} // Note: delete the {} and put the name of your params, if you use a method that passes in params.
})
}
},
components: { ChildComponent },
})
Mohgaderi의 하위 구성 요소 코드와 내 변경 사항에 대한 참고 사항:
import { objectToString } from "@vue/shared"
export default {
name: 'ChildComponent',
props: {
methodsQueue: { type: Array },
},
// Note: I had to rewrite the watch option because it would not trigger.
// You have to add "deep, true" for arrays and objects.
// The function has to be called "handler" for it to work as well.
watch: {
methodsQueue: {
handler() {
this.processMethodsQueue()
},
deep: true,
}
},
// Note: Remove "mounted()" function if you don't want it to run on the mounted event.
mounted() {
this.processMethodsQueue()
},
methods: {
save() {
console.log("Child saved...")
},
processMethodsQueue() {
if (!this.methodsQueue) return
let len = this.methodsQueue.length
if (!len) return // Note: This is required to prevent an infinite loop.
// When we reset the childMethodsQueue array to empty,
// it will trigger this method through the watch option,
// so we need this in order to stop the cycle once we are done.
// Note: Instead of using ".shift()" to access an item in the array
// we need to use "[i]" otherwise we will get muliple calls of the method
for (let i = 0; i < len; i++) {
let method = this.methodsQueue[i]
this[method.name](method.params)
}
// Note: Now that we are done calling methods, we need to emit an event back to the parent
// so it can call it's method to reset the childMethodsQueue array to empty
this.$emit('child-methods-finished')
},
},
}
자식 구성 요소를 다른 자식 구성 요소와 통신하려면 부모에서 자식 구성 요소의 메서드를 호출하는 방법을 만들었습니다.
this.$refs.childRef.childMethod()
childRef는 자식 구성 요소 및 자식 구성 요소의 참조입니다. 메서드는 자식 구성 요소에 있는 모든 메서드로 대체할 수 있습니다.
그리고 또 다른 아이로부터 나는 루트 메소드라고 불렀습니다.
this.$root.theParentMethod() // It works with Bootstrap Vue
this.$parent.theParentMethod()
그것은 나에게 효과가 있었다.
언급URL : https://stackoverflow.com/questions/40957008/how-to-access-to-a-child-method-from-the-parent-in-vue-js
'programing' 카테고리의 다른 글
| fclose return value check (0) | 2023.10.14 |
|---|---|
| CUDA의 __공유_메모리는 언제 유용합니까? (0) | 2023.10.14 |
| scikit 카운트 벡터라이저에서 min_df 및 max_df 이해 (0) | 2023.10.09 |
| Oracle에서 조건부로 삽입하는 방법은 무엇입니까? (0) | 2023.10.09 |
| Google +1에서 마우스 움직임을 기록하는 이유는 무엇입니까? (0) | 2023.10.09 |