我有两个嵌套的组件,从父级访问子级方法的正确方法是什么?
this.$children[0].myMethod()
似乎可以解决问题,但这很丑陋,不是吗,还有什么更好的方法:
<script>
import child from './my-child'
export default {
components: {
child
},
mounted () {
this.$children[0].myMethod()
}
}
</script>
我有两个嵌套的组件,从父级访问子级方法的正确方法是什么?
this.$children[0].myMethod()
似乎可以解决问题,但这很丑陋,不是吗,还有什么更好的方法:
<script>
import child from './my-child'
export default {
components: {
child
},
mounted () {
this.$children[0].myMethod()
}
}
</script>
Answers:
您可以使用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/
this.$refs.
,则不应动态加载子组件。
假定所有后代都可以通过访问Vue根实例,则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
。因此,我决定采用一种更简单的方法。
这个想法是使用数组作为队列将需要调用的方法发送到子组件。一旦安装了组件,它将处理此队列。它监视队列以执行新方法。
(借用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
到mixin ...