vue的几种组件之间数据传输的方式
以下是自己目前学习到的:
1.父传子:这里通常就用最简单的props传递的方式
实例:
父组件通过props的方式向子组件传递数据
<template>
<!-- 这是父组件 -->
<div class="section">
<com-article :articles="articleList"></com-article>
</div>
</template>
<script>
import comArticle from './article.vue'
export default {
name: 'HelloWorld',
components: { comArticle },
data() {
return {
articleList: ['红楼梦', '西游记', '三国演义']
}
}
}
</script>
<style>
</style>
<template>
<!-- 这是子组件 -->
<div>
<span v-for="(item, index) in articles" :key="index">{{item}}</span>
</div>
</template>
<script>
export default {
props: ['articles']
}
</script>
<style>
</style>
2.子索取父 也可比喻成父传子:$parent/$children
好像这个方法到了vue3已经不用了 了解就好
<template>
<div >
<div>{{msg}}</div>
<childern />
<button @click="changeA">点击改变子组件的值</button>
</div>
</template>
<script>
import childern from './children.vue'
export default {
name:'Parent',
components:{childern},
data() {
return {
msg:"我是父组件实例"
}
},
methods:{
changeA()
{
this.$children[0].messageA = 'this is new value'
}
}
}
</script>
<style>
</style>
<template>
<div >
<span>{{messageA}}</span>
<p>获取父组件的值为: {{parentVal}}</p>
</div>
</template>
<script>
export default {
data() {
return {
messageA:"this is old"
}
},
computed:{
parentVal()
{
return this.$parent.msg;
}
}
}
</script>
<style>
</style>
3.子传父:这里叶可以使用props传递函数,通过函数的参数传递
用参数把需要的数据传回来
<template>
<!-- 这是父组件 -->
<div>
<h1>我是父组件大王的儿子小王{{wanname}}</h1>
<Demo2 :getName = "getName"/>
</div>
</template>
<script>
import Demo2 from './demo2.vue'
export default {
name:'Demo1',
components:{Demo2},
data() {
return {
wanname:" "
}
},
methods:{
getName(name)
{
console.log("接收到了儿子的名字",name)
this.wanname = name
}
}
}
</script>
<style>
</style>
<template>
<!-- 这是子组件 -->
<div>
我是子组件小王{{name}}
</div>
</template>
<script>
export default {
name:'Demo2',
props:['getName'],
data() {
return {
name:"王二狗"
}
},
mounted()
{
this.getName(this.name)
}
}
</script>
<style>
</style>
4.子传父:这里使用$emit自定义方式传递
这和上面的哪个非常非常像 本质我感觉差不多 都是依赖参数传递
最最重要的区别就是不通过props传递 这个方法其实也是Vue官方推荐的方法
过程是这样的:$emit绑定一个自定义事件, 当这个语句被执行时, 就会将参数arg传递给父组件,父组件通过v-on监听并接收参数。
其中的@是v-on的简写
我还是推荐这种方法 我第一次学子传父是上面的方法 但是归根还是不规划Props里面的东西还是不要乱动会比较好,而且下面这个方法可以传多个数据,项目里面也用到的多
<template>
<!-- 这是父组件 -->
<div>
<h1>我是父组件大王的儿子小王{{wanname}}</h1>
<Demo2 @getName = "getName"/>
</div>
</template>
<script>
import Demo2 from './demo2.vue'
export default {
name:'Demo1',
components:{Demo2},
data() {
return {
wanname:" "
}
},
methods:{
getName(name)
{
console.log("接收到了儿子的名字",name)
this.wanname = name
}
}
}
</script>
<style>
</style>
<template>
<!-- 这是子组件 -->
<div>
我是子组件小王{{name}}
</div>
</template>
<script>
export default {
name:'Demo2',
// props:['getName'],
data() {
return {
name:"王二狗"
}
},
mounted()
{
// this.getName(this.name)
this.$emit('getName',this.name)
}
}
</script>
<style>
</style>
5.任意组件之间传递:全局事件总线eventbus
EventBus 是中央事件总线,不管是父子组件,兄弟组件,跨层级组件等都可以使用它完成通信操作
这里最重要的就是需要啊根目录下面也就是new vue哪个地方配置一个中央事件总线
这个好像vue3已经不用啦!
//main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
beforeCreate()
{
Vue.prototype.$bus = this
}
}).$mount('#app')
然后在app组件里面挂载需要的
methods: {
//添加一个todo
addTodo(todoObj)
{
this.todos.unshift(todoObj)
},
//取消勾选一个todu
checkTodo(id){
this.todos.forEach((todo)=>{
if(todo.id === id)
{
todo.done = !todo.done
}
})
},
//删除一个todo
deleteTodo(id)
{
this.todos = this.todos.filter((todo)=>{
return todo.id !== id
})
},
//全选or全不选
checkAllTodo(done)
{
this.todos.forEach((todo)=>{
todo.done = done
})
},
// 清除所有已经完成的todo
clearAllTodo()
{
this.todos = this.todos.filter = ((todo)=>{
return !todo.done
})
},
//跟新一个Todo
updateTodo(id,title)
{
this.todos.forEach((todo)=>{
if(todo.id === id) todo.title = title
})
},
},
mounted()
{
this.$bus.$on('checkTodo',this.checkTodo)
this.$bus.$on('updateTodo',this.updateTodo)
this.$bus.$on('deleteTodo',this.deleteTodo)
},
beforeDestroy()
{
this.$bus.$off('checkTodo')
this.$bus.$off('deleteTodo')
this.$bus.$off('updateTodo')
}
在需要的时候直接调用
handleBlur(todo,e)
{
//失去焦点回调(真正执行修改逻辑)
todo.isEdit = false
console.log('updateTodo',todo.id,e.target.value)
if(!e.target.value.trim()) return alert("输入不能为空")
this.$bus.$emit('updateTodo',todo.id,e.target.value)
}
因为这个单独写比较麻烦 这里展示需要的部分 需要看全部的可以直接看我的源码
https://gitee.com/tianlongren/todo-list
6.任意组件之间传递:借助有关插件使用消息订阅与发布
这个需要借用插件 vue 用的比较少 react用的非常多
详情可以看掘金文章
7.provide/inject
provide / inject 为依赖注入
这个是vue2.2新增加的api vue3也还在用 比较推荐 特别是用于 爷组件和孙组件的通信
provide:可以让我们指定想要提供给后代组件的数据或
inject:在任何后代组件中接收想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来用
vue3中还在使用
<template>
<div>
<comB></comB>
</div>
</template>
<script>
import comB from './B.vue'
export default {
name:'A',
provide:{
for:"艾欧尼亚",
},
data() {
return {
}
},
components:{
comB
}
}
</script>
<style>
</style>
<template>
<div>
我是子组件-----{{demo}}
<comC></comC>
</div>
</template>
<script>
import comC from './C.vue'
export default {
name:"B",
provide:{
abc:"诺克萨斯"
},
inject:['for'],
data()
{
return {
demo:this.for
}
},
components:{
comC
}
}
</script>
<style>
.student{
background-color: pink;
}
</style>
<template>
<div>
我是孙组件-----{{demo}}
<h3>我是孙组件-----{{abc}}</h3>
</div>
</template>
<script>
export default {
name: "C",
inject: ['for','abc'],
data() {
return {
demo: this.for,
abc:this.abc
}
}
}
</script>
<style>
</style>
运行结果:
8.子传父 ref/$ref
这里本质是上使用到了ref属性的一个特点
vue 3中依然有ref 所以这个还是可以用的 但是vue3之后出了一个新的方法
也用到了不过哪个我目前确实还不懂 先搁置
vue官网对ref的表述 注意子组件 引用指向实例就代表可以使用实例子组件的全部东西 比如方法 data数据等等
这是父组件
<template>
<div>
<h1 v-text="msg" ref="title"></h1>
<h2>{{mm}}</h2>
<button @click="showDOM" ref="btn" >点我输入上方的dom元素</button>
<School ref="sch"/>
</div>
</template>
<script>
import School from './components/School.vue'
export default {
name:'App',
components:{School},
export default {
data() {
return {
sch:"001"
}
},
methods:{
showDOM()
{
console.log(this.$refs.title)//真实dom元素
console.log(this.$refs.btn)//真实dom元素
console.log(this.$refs.sch.sch)//子组件中的
this.mm = this.$refs.sch.sch //赋值一波
}
}
}
}
</script>
//这里是子组件
<template>
<div>
我是School组件
</div>
</template>
<script>
export default {
data() {
return {
sch:"001"
}
},
}
</script>
<style>
</style>
9.终极解决方案:Vuex
这个是大型项目中组件通信的终极解决方法 我个人认为和消息订阅与发布都是很像的 通过引入插件的方式完成通信
Vuex多个组件之间的数据的通信由其是要各种跨组件的的时候很好用特别是兄弟组件跨越,并且可以很好的进行组件之间的数据维护 可以说是vue项目中的终极解决方案了
Vuex 还可以在数据传输的时候对数据进行处理 十分的强大
这边建议直接看掘金上大佬的文章:https://juejin.cn/post/7087100496762109983#heading-7
OK以上就是我对于vue组件之间通信的掌握
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程