首页IT科技vue父子组件传值props(Vue2-父子组件传值)

vue父子组件传值props(Vue2-父子组件传值)

时间2025-06-17 19:35:29分类IT科技浏览4959
导读:在日常开发中,我们经常会在一个组件中嵌套另外一个组件,那么如果我们父组件要向子组件传值该怎么办?子组件向父组件通信又该怎么办?本文将详细举例说明这些问题。...

在日常开发中              ,我们经常会在一个组件中嵌套另外一个组件                    ,那么如果我们父组件要向子组件传值该怎么办?子组件向父组件通信又该怎么办?本文将详细举例说明这些问题              。

父向子通信

问题描述

现在我们有个需求       ,我们要分别显示父和子的信息       ,我们当然可以在一个组件中直接显示全部信息                    ,但是万一以后又来一个需求:我们要在母和子的信息             ,那其实这里就存在冗余了       ,所以我们把子组件单独封装成一个新的组件                    。那么这里就会出现一个问题                     ,子组件的信息该如何从父组件传过去呢?

解决方案

使用vue提供的prop属性             ,下面边看代码边分析:

父组件定义 <template> <div class="father"> 这里是父组件,我们会在这里展示父的信息 {{ fatherName }} {{ fatherAge }} <son/> </div> </template> <script> import son from "@/components/son"; export default { name: "father", components: { son }, data() { return { fatherName: "张三", fatherAge: 12 } } } </script> <style lang="css"> .father{ border: 1px solid black; } </style>

子组件定义

<template> <div class="son"> 这里是子组件                     ,我们会在这里展示子的信息 </div> </template> <script> export default { name: "son" } </script> <style scoped> .son{ margin: 10px; border: 1px solid red; } </style>

使用:attribute属性向子组件传入值

<template> <div class="father"> 这里是父组件                    ,我们会在这里展示父的信息 {{ fatherName }} {{ fatherAge }} <son :sonInfo="sonInfo"/> </div> </template> <script> import son from "@/components/son"; export default { name: "father", components: { son }, data() { return { fatherName: "张三", fatherAge: 12, sonInfo: { sonName: "王小虎", sonAge: 6 } } } } </script> <style lang="css"> .father { border: 1px solid black; } </style>

子组件通过props属性接收父组件传过来的值,这里的名字要和父组件传的值对应

<template> <div class="son"> 这里是子组件              ,我们会在这里展示子的信息 {{ sonInfo.sonName }} {{ sonInfo.sonAge }} </div> </template> <script> export default { name: "son", props: ["sonInfo"] } </script> <style scoped> .son { margin: 10px; border: 1px solid red; } </style>

测试

扩展

上述的例子解决了父子组件传值的基本问题                    ,当然prop的用法还有很多       ,我们可以在vue2官网上看到

Prop的大小写

camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名

Vue.component(blog-post, { // 在 JavaScript 中是 camelCase 的 props: [postTitle], template: <h3>{{ postTitle }}</h3> }) <!-- 在 HTML 中是 kebab-case 的 --> <blog-post post-title="hello!"></blog-post>

Prop 类型

我们之前使用以字符串数组形式列出的 prop

props: ["sonInfo"]

我们也可以给每一个prop指定对应的值

props: { title: String,//字符串 likes: Number,//数字 isPublished: Boolean,//布尔 commentIds: Array,//数组 author: Object,//对象 callback: Function,//函数 contactsPromise: Promise //异步延迟对象 }

传递静态或动态 Prop

之前我们传递的是动态的Prop              ,可以动态赋值

<son :sonInfo="sonInfo"/>

我们也可以传递静态的

<son :sonInfo="sonInfo" sex="1"/> props: ["sonInfo", "sex"]

单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定

:父级 prop 的更新会向下流动到子组件中                    ,但是反过来则不行       。这样会防止从子组件意外变更父级组件的状态       ,从而导致你的应用的数据流向难以理解       。

额外的       ,每次父级组件发生变更时                    ,子组件中所有的 prop 都将会刷新为最新的值                    。这意味着你应该在一个子组件内部改变 prop             。如果你这样做了             ,Vue 会在浏览器的控制台中发出警告       。

官方这段话表明了       ,我们对于父组件传过来的值最不要直接修改                     ,官方例举了两个常用的变更案例

1.这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用 props: [initialCounter], data: function () { return { counter: this.initialCounter } }

2.这个 prop 以一种原始的值传入且需要进行转换

props: [size], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }

类型校验

之前我们使用字符串数组形式列出的 prop             ,父组件不知道子组件prop值的类型,可能传值的时候传错                     ,所以我们可以给值指定类型                     。如果有一个需求没有被满足                    ,则 Vue 会在浏览器控制台中警告你

Vue.component(my-component, { props: { // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: hello } } }, // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return [success, warning, danger].includes(value) } } } })

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告

子向父通信

问题描述

既然父可以向子传值              ,那么子是否可以通信父呢?当然可以                    ,这时候我们要借助vue的

e

m

i

t

emit和

emiton       ,下面我们看代码:

解决方案

子组件

<template> <div class="son"> 这里是子组件 <button @click="emit">使用emit向父组件通信</button> </div> </template> <script> export default { name: "son", methods:{ emit(){ this.$emit(sayHi,"tom") } } } </script> <style scoped> .son { margin: 10px; border: 1px solid red; } </style>

父组件

<template> <div class="father"> 这里是父组件 <son sex="1" @sayHi="sayHi"/> </div> </template> <script> import son from "@/components/son"; export default { name: "father", components: { son }, data() { return {} }, methods: { sayHi(name) { console.log("sayHi:"+name) } } } </script> <style lang="css"> .father { border: 1px solid black; } </style>

测试

点击按钮              ,控制台输出sayHi tom

分析

这里首先介绍一下vue提供的两个重要函数emit和on

on

监听当前实例上的自定义事件             。事件可以由 $emit 触发。回调函数会接收所有传入事件触发函数的额外参数                     。

上述例子的 @sayHi="sayHi"就是在监听sayHi事件                    ,这里采用了简写形式       ,完整形式是v-on:sayHi=“sayHi              ”       ,我们平时用的比较多的就是监听点击事件                    ,而这里我们就是监听了我们自定义的事件

emit

触发当前实例上的事件                    。附加参数都会传给监听器回调。

当我们监听了自定义事件             ,我们就可以在子组件中触发事件       ,this.$emit(‘sayHi’,“tom                    ”)                     ,这样就会调用监听的回调函数             ,并且将附加参数tom传入回调函数

非父子通信

除了上述的父子组件通信,我们最后还可以在非父子组件之间传值                     ,某些场景下会用到              。下面看代码:

事件总线 import Vue from "vue"; export default new Vue;

组件B

<template> <div> 组件B {{ value }} </div> </template> <script> import bus from "@/components/bus"; export default { name: "ComponentB", data() { return { value: "oldVal" } }, created() { bus.$on("changeVal", newVal => { this.value = "newVal" }) } } </script> <style scoped> </style>

组件A

<template> <div> 组件A <button @click="communicate">组件A->组件B</button> </div> </template> <script> import bus from "@/components/bus"; export default { name: "ComponentA", methods:{ communicate(){ bus.$emit("changeVal","newVal") } } } </script> <style scoped> </style>

测试

组件B的值由oldVal->newVal

分析

这里引入了事件总线(event bus)的概念                    ,事件总线:事件发送者将事件消息发送到一个事件总线上,事件订阅者向事件总线订阅和接收事件              ,然后再处理接收到的事件

而我们这里的事件总线的载体就是一个Vue的实例对象                    ,因为在emit和on都是Vue的一个实例方法                    。

当然我们还可以使用$attrs / listeners来实现类似效果       ,这里就不多做介绍了              ,有兴趣的读者可以自行了解

但是如果学过Vuex的话                    ,利用Vuex来传值会很方便       ,Vuex之后会慢慢讲       ,不急       。学习是个漫长的过程                    ,慢慢来

由于作者能力有限             ,若有错误或者不当之处       ,还请大家批评指正                     ,一起学习交流!

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
从中老年人广场舞看待网站优化(探究中老年人对网站优化的认知和需求) 网上创业机会的几个途径(如何能网创100万-巧借信息差,通过微信混圈子就能赚钱)