我已经阅读了很多关于此的文章,似乎有多种方法可以做到这一点,许多作者建议不要使用某些实现。
为了简化这个过程,我创建了一个我想要实现的非常简单的版本。
我有一个父 Vue,parent.vue。它有一个按钮:
<template>
<div>
<button v-on:click="XXXXX call method in child XXXX">Say Hello</button>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
在子Vue中,child.vue我有一个带函数的方法:
methods: {
sayHello() {
alert('hello');
}
}
Run Code Online (Sandbox Code Playgroud)
我想sayHello()
在单击父级中的按钮时调用该函数。
我正在寻找执行此操作的最佳实践方法。我看到的建议包括事件总线、子组件引用和道具等。
在我的方法中执行函数的最简单方法是什么?
抱歉,这看起来确实非常简单,但我确实尝试过做一些研究。
谢谢!
Fla*_*ame 56
一种简单的方法是这样做:
<!-- parent.vue -->
<template>
<button @click="$refs.myChild.sayHello()">Click me</button>
<child-component ref="myChild" />
</template>
Run Code Online (Sandbox Code Playgroud)
只需ref
为子组件创建一个,您就可以调用这些方法,并访问它拥有的所有数据。
Jon*_*s m 41
我不喜欢使用 props 作为触发器的外观,但使用 ref 似乎也是一种反模式,通常不推荐。
另一种方法可能是:您可以使用事件公开方法接口来调用子组件,这样您就可以获得两全其美的效果,同时保持代码整洁。只需在安装阶段发射它们,并在需要时使用它们。我将其存储在下面代码中的 $options 部分中,但您可以随意执行。
子组件
<template>
<div>
<p>I was called {{ count }} times.</p>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
<script>
export default {
mounted() {
// Emits on mount
this.emitInterface();
},
data() {
return {
count: 0
}
},
methods: {
addCount() {
this.count++;
},
notCallable() {
this.count--;
},
/**
* Emitting an interface with callable methods from outside
*/
emitInterface() {
this.$emit("interface", {
addCount: () => this.addCount()
});
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
父组件
<template>
<div>
<button v-on:click="addCount">Add count to child</button>
<child-component @interface="getChildInterface"></child-component>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
<script>
export default {
// Add a default
childInterface: {
addCount: () => {}
},
methods: {
// Setting the interface when emitted from child
getChildInterface(childInterface) {
this.$options.childInterface = childInterface;
},
// Add count through the interface
addCount() {
this.$options.childInterface.addCount();
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
MrS*_*Spt 29
通过 vue 3 组合 api,您可以使用defineExpose
. 更多信息可以在这里找到
家长.vue
<script setup lang="ts">
const childRef = ref()
const callSayHello = () => {
childRef.value.sayHello()
}
</script>
<template>
<child ref="childRef"></child>
</template>
<style scoped></style>
Run Code Online (Sandbox Code Playgroud)
儿童.vue
<script setup lang="ts">
const sayHello = () => {
console.log('Hello')
}
defineExpose({ sayHello })
</script>
<template></template>
<style scoped></style>
Run Code Online (Sandbox Code Playgroud)
Rad*_*iță 20
您可以创建一个ref
并访问这些方法,但不建议这样做。您不应该依赖组件的内部结构。这样做的原因是您将紧密耦合组件,而创建组件的主要原因之一是松散耦合。
您应该依靠contract
(某些框架/语言中的接口)来实现这一点。将contract
在Vue
依赖于家长通过与孩子沟通的事实props
,并children
与之通信parent
通过events
。
当您想在非父/子组件之间进行通信时,还有至少 2 种其他方法可以进行通信:
我现在将描述如何使用道具:
1.在你的子组件上定义
props: ['testProp'],
methods: {
sayHello() {
alert('hello');
}
}
Run Code Online (Sandbox Code Playgroud)
2.在父组件上定义一个触发器数据
data () {
return {
trigger: 0
}
}
Run Code Online (Sandbox Code Playgroud)
3.在父组件上使用prop
<template>
<div>
<childComponent :testProp="trigger"/>
</div>
</template>
Run Code Online (Sandbox Code Playgroud)
4.testProp
在子组件中watch并调用sayHello
watch: {
testProp: function(newVal, oldVal) {
this.sayHello()
}
}
Run Code Online (Sandbox Code Playgroud)
5.trigger
从父组件更新。确保始终更改 的值trigger
,否则watch
不会触发。一种方法是增加触发器,或将其从真值切换为假值(this.trigger = !this.trigger)
归档时间: |
|
查看次数: |
28095 次 |
最近记录: |