当前位置: 首页 > news >正文

Vue3——父子组件通信

    在Vue开发中,组件通信是核心概念之一。良好的组件通信机制能让我们的应用更加清晰、可维护。

父传子defineProps

    defineProps是一个编译时宏,仅在内部可用,不需要显式导入。声明的 props 会自动暴露给模板。 还返回一个对象,其中包含传递给组件的所有 props,以便我们可以根据需要在 JavaScript 中访问它们:<script setup>defineProps(在一个组件中仅可使用一次)

    在使用前先准备两个父子关系的组件:

<script setup>
import Son from './components/Son.vue';
</script><template><div>我是父组件App.vue<Son></Son></div>
</template><style scoped></style>
<script setup></script><template><div>我是子组件Son.app</div>
</template><style scoped></style>

当前的效果为:

     想要实现父传子的效果,首先要在父组件中定义好数据,在子组件的标签中通过绑定自定义属性的方式,给定一个值;在子组件中使用defineProps函数接收,这其中有很多种情况。

    defineProps()内可使用数组语法或对象语法接收:

数组语法:

  • 使用中括号接收[]
  • 仅声明传递数据的名称,不需要指定类型或其他配置

对象语法:

  • 使用大括号接收{}
  • 需指定传递类型,可指定是否必填,默认值,自定义校验函数等。

注:父组件的中的子标签自定义属性必须与defineProps接收的名称保持一致,或者父组件中使用HTML特性规范,子组件中使用小驼峰命规范 


传递静态数据

数组接收

<script setup>
import Son from './components/Son.vue';
</script><template><div>我是父组件App.vue<Son :props-a="666"></Son></div>
</template><style scoped></style>

使用时可直接使用{{propsA}}或{{b.propsA}} 

<script setup>
const b = defineProps(["propsA"])
</script><template><div>父组件传的值为--{{ b.propsA }}</div>
</template><style scoped></style>
<script setup>
const b = defineProps(["propsA"])
</script><template><div>父组件传的值为--{{ propsA }}</div>
</template><style scoped></style>

<script setup>
import Son from './components/Son.vue';
</script><template><div>我是父组件App.vue<Son :props-a="666" :props-num="'Stringa'"></Son></div>
</template><style scoped></style>
<script setup>
const b = defineProps(["propsA","propsNum"])
</script><template><div>父组件传的值为--{{ propsA }}{{ b.propsNum }}</div>
</template><style scoped></style>

 对象接收

<script setup>
const b = defineProps({"propsA":Number,"propsNum":String})
</script><template><div>父组件传的值为--{{ propsA }}{{ b.propsNum }}</div>
</template><style scoped></style>

传递对象数据

一般情况下传递的值都是响应式的:

<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';const str = ref("AppString")
const obj = ref({msg:"ObjectMsg",massage:"ObjMassage"
})
</script><template><div>我是父组件App.vue<Son :props-a="str" :props-num="obj"></Son></div>
</template><style scoped></style>

数组接收

<script setup>
const b = defineProps(["propsA","propsNum"])
</script><template><div>父组件传的值为--{{ propsA }}{{ b.propsNum }}</div>
</template><style scoped></style>

这里可以直接使用b.propsNum.msg,不需要.value(在script也是一样),因为父组件在传递整个ref对象时会自动解包,传递ref对象的某个属性时也一样:

<script setup>
const b = defineProps(["propsA","propsNum"])
console.log(b.propsNum);</script><template><div>父组件传的值为--{{ propsA }}-{{ b.propsNum }}</div>
</template><style scoped></style>

对象接收 

使用对象接收时要理清楚接收的类型,传递对象时可直接使用一个大括号

<script setup>
const b = defineProps({"propsA":String ,"propsNum":{}
})</script><template><div>父组件传的值为--{{ propsA }}-{{ b.propsNum }}</div>
</template><style scoped></style>

 不过应该指定其它的类型Object:

<script setup>
const b = defineProps({"propsA":String ,"propsNum":Object
})</script><template><div>父组件传的值为--{{ propsA }}-{{ b.propsNum }}</div>
</template><style scoped></style>

 

注意:如果父组件直接传递一个响应式数据,那么子组件可以直接修改父组件的值。

<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';const str = ref("AppString")
const obj = ref({msg:"ObjectMsg",massage:"ObjMassage",num:88
})
</script><template><div>我是父组件App.vue{{ obj.msg }}<Son :props-a="str" :props-num="obj"></Son></div>
</template><style scoped></style>
<script setup>
const b = defineProps({"propsA":String ,"propsNum":Object
})
const ad =()=>{b.propsNum.msg = "ooooo"
}</script><template><div>父组件传的值为--{{ propsA }}-{{ b.propsNum.msg }}<button @click="ad">修改值</button></div>
</template><style scoped></style>

此时点击修改值,会直接修改父组件中的值:

如果传递的是响应式对象的属性,则子组件不能修改其值。

 

 props 展开

    当父组件向子组件传递数据时,如果直接使用 v-bind="object" 而不指定具体属性名,这称为 "props 展开" 或 "对象绑定"。这种方式会将对象的所有属性自动展开为单独的 props。

注:在子组件接收时,属性名和父组件中的属性值要一致

<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';const obj = ref({msg:"ObjectMsg",massage:"ObjMassage",num:88
})
</script><template><div>我是父组件App.vue{{ obj.msg }}<Son :="obj"></Son></div>
</template><style scoped></style>
<script setup>
const b = defineProps({msg:String,massage:String,num:Number
})</script><template><div>父组件传的值为--{{b.msg}}</div>
</template><style scoped></style>

 在子组件中接收时缺少属性时不会报错,添加属性时,可以使用default给它默认值:

<script setup>
const b = defineProps({msg:String,massage:String,num:Number,aa:{type:Number,required:true,default:200}
})</script><template><div>父组件传的值为--{{b.msg}}{{ b.aa }}</div>
</template><style scoped></style>

子传父defineEmits

defineEmits 用于声明组件可以触发的自定义事件(子组件向父组件通信)

使用步骤:

  1. 用defineEmits定义事件名,得到emits对象
  2. 用emits函数指定事件名,并传递数据
  3. 父组件接收时,在子组件标签中触发子组件定义的事件,触发的函数的参数就是传递过来的值

<script setup>
import { reactive } from 'vue';
const emit = defineEmits(['e_app'])const data = reactive({msg:""
})const btn = ()=>{emit('e_app',data)
}
</script><template><div><input type="text" v-model="data.msg"><button @click="btn">提交给父组件</button></div>
</template><style scoped></style>
<script setup>
import Son from './components/Son.vue';
import { ref } from 'vue';const app =(data) =>{console.log(data.msg);massage.value = data.msg
}const massage = ref("")
</script><template><div>我是父组件{{ massage }}<Son @e_app="app"></Son></div>
</template><style scoped></style>

相关文章:

  • Android7 Input(七)App与input系统服务建立连接
  • 灵光一现的问题和常见错误1
  • 搭建基于Windows平台的http文件服务(miniserve+filebrowser+nssm)
  • Datawhale PyPOTS时间序列5月第3次笔记
  • 湖北理元理律师事务所:债务优化中的双维支持实践解析
  • 一分钟用 MCP 上线一个 贪吃蛇 小游戏(CodeBuddy版)
  • java中的运算符
  • 多线程(4)——线程安全,锁
  • 数学复习笔记 16
  • 在 Linux 上安装 MATLAB:完整指南与疑难解决方案
  • 交流学习 | 江西同为科技有限公司赴海尔总部考察交流
  • Spring源码之解决循环依赖 三级缓存
  • Python二进制运算:高效操作与实用技巧
  • OpenHarmony外设驱动使用 (二),Camera
  • [ctfshow web入门] web118
  • hysAnalyser 从MPEG-TS导出ES功能说明
  • Leaflet使用SVG创建动态Legend
  • wifiactivity 界面 要在哪里注册,注销广播?onResume() vs onPause() 的本质区别
  • 安装nerdctl和buildkitd脚本命令
  • LLM智能体新纪元:深入解析MCP与A2A协议,赋能智能自动化协作
  • 金属建材企业网站建设方案/东莞网络推广及优化
  • php建设网站/最新国内你新闻
  • bootstrap单页网站/seo方法图片
  • 风铃网站具体是做那方面的/优化关键词排名哪家好
  • 网站建设和/优质网站
  • 广州天河酒店网站建设/找网站公司制作网站