(选项式)Vue父子组件传值&传递方法及可能出现的问题
在 Vue 中,父子组件可以通过以下方式传递值和方法:
Vue(选项式)组件传值
父传子:通过 props
传递值
父组件通过 props
将数据传递给子组件。
示例:
子组件:
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: {//定义父组件传递props名称
type: String,//父组件传递是字符串类型就定义相同的,常见array,object类型
required: true,
},
},
};
</script>
父组件:
<template>
<div>
<!-- 将父组件的数据,通过子组件命名相同的props名称,传递数值,确保和子组件定义的类型一致,这里是字符串类型 -->
<ChildComponent :message="parentMessage" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
parentMessage: 'Hello from Parent',//字符串类型
};
},
};
</script>
子传父:通过 emit
向父组件传递值
子组件通过 $emit
向父组件发送事件。
示例:
子组件:
<template>
<div>
<button @click="sendMessage">Send Message to Parent</button>
</div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('updateMessage', 'Hello from Child');
//this.$emit('父组件接收方法名称', '接收参数')
},
},
};
</script>
父组件:
<template>
<div>
<!-- @子组件定义抛出方法名称="父组件方法"-->
<ChildComponent @updateMessage="updateParentMessage" />
<p>Message from Child: {{ messageFromChild }}</p>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
messageFromChild: '',
};
},
methods: {
//调用父组件方法触发子组件方法
updateParentMessage(newMessage) {
this.messageFromChild = newMessage;
},
},
};
</script>
父传子:传递方法
父组件可以将方法作为 props
传递给子组件,子组件调用方法时直接使用。
示例:
父组件:
<template>
<div>
<ChildComponent :handleClick="parentMethod" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
parentMethod() {
console.log('Method from Parent');
},
},
};
</script>
子组件:
<template>
<div>
<button @click="handleClick">Call Parent Method</button>
</div>
</template>
<script>
export default {
props: {
handleClick: {
type: Function,
required: true,
},
},
};
</script>
总结
- 父传子:使用
props
。 - 子传父:使用
$emit
。 - 父传子方法:将方法作为
props
传递。
根据具体需求灵活选择合适的传值方式。
可能出现的问题
【警告】父子传递方法看你会出现暴露声明emits警告
该错误提示表明,在一个 Vue 组件中,您传递了自定义事件监听器(比如 getReward
和 getContribute
),但组件的模板中可能是一个Fragment或者文本根节点,Vue 无法自动处理这些事件。
什么是 Fragment 或文本根节点?
- Fragment:Vue 组件的模板根节点包含多个元素,而不是一个单独的根节点。
- 文本根节点:组件的模板内容是纯文本而非 HTML 元素。
Vue 要求组件监听的事件必须在 emits
选项中声明,未声明的事件会触发上述警告。
如何解决问题?
1. 在子组件声明 emits
当子组件触发自定义事件时,应该在 emits
选项中显式声明这些事件。例如:
子组件:
<template>
<div>
<button @click="$emit('getReward')">Get Reward</button>
<button @click="$emit('getContribute')">Get Contribute Reward</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
emits: ['getReward', 'getContribute'], // 子组件需要声明自定义事件
};
</script>
2. 父组件监听子组件事件
父组件通过自定义事件监听子组件的操作。
父组件:
<template>
<div>
<ChildComponent
@getReward="handleGetReward"
@getContribute="handleGetContributeReward"
/>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
handleGetReward() {
console.log('Reward received');
},
handleGetContributeReward() {
console.log('Contribute reward received');
},
},
};
</script>
3. 确保组件有一个单一根节点(避免 Fragment 问题)
如果子组件的模板中有多个根节点,确保将它们包裹在一个父节点内,例如 div
。
正确:
<template>
<div>
<header>Header</header>
<main>Main Content</main>
</div>
</template>
错误:
<template>
<header>Header</header>
<main>Main Content</main>
</template>
总结
这个错误与 Vue 3 的事件监听规范和组件根节点结构有关:
- 声明
emits
:在子组件中声明所有的自定义事件。 - 根节点管理:确保子组件的模板有一个唯一的根节点。
- 父组件监听:在父组件中正确绑定自定义事件。
通过以上调整可以解决警告。
原文地址:https://blog.csdn.net/m0_47814717/article/details/145187842
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!