al3*_*l3x 59 javascript vue.js
我有两个嵌套组件,从父级访问子方法的正确方法是什么?
this.$children[0].myMethod() 似乎做了伎俩,但它很丑,不是吗,有什么更好的方法:
<script>
import child from './my-child'
export default {
components: {
child
},
mounted () {
this.$children[0].myMethod()
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
Des*_*Lua 168
你可以使用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 },
})
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢紧耦合,可以使用@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 },
})
Run Code Online (Sandbox Code Playgroud)
组件代码.
<template>
...
</template>
<script>
export default {
name: 'NowForm',
props: ['item', 'bus'],
methods: {
submit() {
...
}
},
mounted() {
this.bus.$on('submit', this.submit)
},
}
</script>
Run Code Online (Sandbox Code Playgroud)
https://code.luasoftware.com/tutorials/vuejs/parent-call-child-component-method/
wob*_*ano 47
对于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>
Run Code Online (Sandbox Code Playgroud)
脚本设置
<!-- Child -->
<script setup>
const doSomething = () => {
console.log('Im batman')
}
defineExpose({
doSomething
})
</script>
Run Code Online (Sandbox Code Playgroud)
设置功能
<!-- Child -->
<script>
import { defineComponent } from 'vue'
export default defineComponent({
setup(props, context) {
const doSomething = () => {
console.log('Im batman')
}
context.expose({ doSomething })
}
})
</script>
Run Code Online (Sandbox Code Playgroud)
尽可能避免这种情况并使用可组合项。除非你无法控制该组件(第三方插件等)。
来源: https: //vuejs.org/api/sfc-script-setup.html#defineexpose
Yos*_*ero 24
鉴于所有后代this.$root都可以访问根Vue实例,父组件可以通过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
}
});Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
从原始帖子中回答:在VueJS中的组件之间进行通信
小智 8
建议的解决方案适用于 Vue 2,但如果您最终在这里寻找 Vue 3 Composition API 解决方案,您可以在迁移时执行以下操作:
模板中的子组件,具有方法 "doSomething" :
<div class="form">
<child-component ref="childComponentRef" />
</div>
Run Code Online (Sandbox Code Playgroud)
使用 Vue 2:
this.$refs.childComponentRef.doSomething( );
Run Code Online (Sandbox Code Playgroud)
使用 Vue 3 Composition Api :
setup( )
{
const childComponentRef = ref( );
childComponentRef.value.doSomething( )
return {
childComponentRef
}
}
Run Code Online (Sandbox Code Playgroud)
当您的控件渲染受到 的影响时,引用和事件总线都会出现问题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 },
})
Run Code Online (Sandbox Code Playgroud)
这是 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>
Run Code Online (Sandbox Code Playgroud)
还有很大的改进空间,比如转向processMethodsQueue混合......
| 归档时间: |
|
| 查看次数: |
72601 次 |
| 最近记录: |