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 },
})
mohghaderi的子组件代码以及有关我的更改的注解:
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')
},
},
}
7条答案
按热度按时间ylamdve61#
您可以使用参考
如果你不喜欢紧耦合,你可以使用事件总线,如@Yosvel Quintero所示。下面是另一个使用事件总线的例子,通过将总线作为 prop 传递。
组件的代码。
https://code.luasoftware.com/tutorials/vuejs/parent-call-child-component-method/
mw3dktmi2#
适用于Vue 2.7和Vue 3.2.x
脚本设置
设置功能
9fkzdhlc3#
VueJS中的父子通信
假设所有后代都可以通过
this.$root
访问一个根Vue示例,父组件可以通过this.$children
数组访问子组件,子组件可以通过this.$parent
访问其父组件,那么您的第一React可能是直接访问这些组件。VueJS文档特别警告不要这样做,原因有两个:
解决方案是使用Vue的自定义事件接口
Vue实现的事件接口允许您在组件树中上下通信。利用自定义事件接口,您可以访问四种方法:
$on()
-允许您在Vue示例上声明侦听器,用于侦听事件$emit()
-允许在同一示例(自身)上触发事件使用
$on()
和$emit()
的示例:第一个
答案摘自原帖:Communicating between components in VueJS
eeq64g8w4#
建议的解决方案适用于Vue 2,但如果您最终在此处寻找Vue 3组合API解决方案,则可以在迁移时执行以下操作:
模板中具有方法“doSomething”的子组件:
使用Vue 2:
使用Vue 3组成API:
cbeh67ev5#
当你的控件呈现受到
v-if
的影响时,Ref和事件总线都有问题。这个想法是使用一个数组作为队列,将需要调用的方法发送给子组件。一旦组件被挂载,它将处理这个队列。它监视队列以执行新的方法。
(借用Desmond Lua回答中的一些代码)
父组件代码:
这是ChildComponent代码
而且还有很大的改进空间,比如将
processMethodsQueue
移到mixin中。gk7wooem6#
我喜欢mohghaderi的答案,但是我遇到了一些问题,所以我将使用他的示例代码来显示我需要做的修改,以便它工作。(在我自己的项目中,我使用的是Vue 3和Options API。)
mohghaderi的父组件代码以及有关我的更改的注解:
mohghaderi的子组件代码以及有关我的更改的注解:
ijnw1ujt7#
为了使一个子组件与另一个子组件进行通信,我在parent中创建了一个方法,该方法使用以下命令调用子组件中的方法:
childRef是子组件的引用,childMethod可以替换为子组件中的任何方法。
从另一个子函数调用root方法:
对我很有效。