【前端–Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

62,562次阅读
没有评论

共计 5875 个字符,预计需要花费 15 分钟才能阅读完成。

 本篇将重点讲解 vue 中的多种组件通信方式,包括【父传子】【子传父】【兄弟组件通信】【依赖注入】等等,并提供具体案例来让小伙伴们加深理解、彻底掌握!喜欢的小伙伴们 点赞收藏,持续关注哦~💕

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

💟 上一篇文章 史上最详细的 Vue 入门教程(六) — 工程化开发和脚手架、组件注册

📝 系列专栏 vue 从基础到起飞

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

目录

一、组件通信

1. 什么是组件通信?

2. 组件关系分类

3. 通信解决方案

4. 父子通信流程

5. 父向子通信代码示例

6. 子向父通信代码示例

二、详解 props

1.Props 定义

2.Props 作用

3. 特点

4. 代码演示

三、props 校验

1. 思考

2. 作用

3. 语法

4. 代码演示

四、props 校验完整写法

1. 语法

2. 代码实例

3. 注意

五、props & data、单向数据流

1. 共同点

2. 区别

3. 单向数据流:

4. 代码演示

5. 口诀

六、非父子通信 — event bus 事件总线

1. 作用

2. 步骤

3. 代码示例

七、非父子通信 — provide&inject

1. 作用

2. 场景

3. 语法

4. 完整实例

5. 总结


一、组件通信

1. 什么是组件通信?

组件通信,就是指 组件与组件 之间的 数据传递

2. 组件关系分类

  1. 父子关系

  2. 非父子关系

3. 通信解决方案

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

4. 父子通信流程

  1. 父组件通过 props 将数据传递给子组件

  2. 子组件利用 $emit 通知父组件修改更新

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

5. 父向子通信代码示例

父组件通过 props 将数据传递给子组件

父组件 App.vue





子组件 Son.vue





父向子传值步骤

  1. 给子组件以添加属性的方式传值

  2. 子组件内部通过 props 接收

  3. 模板中直接使用 props 接收的值

6. 子向父通信代码示例

子组件利用 $emit 通知父组件,进行修改更新

子组件 Son.vue





 父组件 App.vue





子向父传值步骤

  1. $emit 触发事件,给父组件发送消息通知

  2. 父组件监听 $emit 触发的事件

  3. 提供处理函数,在函数的性参中获取传过来的参数

二、详解 props

1.Props 定义

组件上 注册的一些 自定义属性

2.Props 作用

向子组件传递数据

3. 特点

  1. 可以 传递 任意数量 的 prop

  2. 可以 传递 任意类型 的 prop

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

4. 代码演示

父组件 App.vue





子组件 UserInfo.vue





三、props 校验

1. 思考

组件的 props 可以乱传吗?

2. 作用

为组件的 prop 指定 验证要求 ,不符合要求,控制台就会有 错误提示 帮助开发者,快速发现错误

3. 语法

  • 类型校验

  • 非空校验

  • 默认值

  • 自定义校验

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

4. 代码演示

App.vue





子组件 BaseProgress.vue(写了一个简单的进度条组件)





实现了进度条显示 50% 的进度,效果图如下:

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

四、props 校验完整写法

1. 语法

props: {
  校验的属性名: {
    type: 类型,  // Number String Boolean ……
    required: true, // 是否必填
    default: 默认值, // 默认值
    validator (value) {
      // 自定义校验逻辑
      return 是否通过校验
    }
  }
},

2. 代码实例

3. 注意

1.default 和 required 一般不同时写 因为当时必填项时,肯定是有值的)

2.default 后面如果是简单类型的值,可以直接写默认值。如果是复杂类型的值,则需要以函数的形式 return 一个默认值

五、props & data、单向数据流

1. 共同点

都可以给组件提供数据

2. 区别

3. 单向数据流:

父级 props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的

4. 代码演示

App.vue





BaseCount.vue





【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

5. 口诀

谁的数据谁负责

六、非父子通信 -- event bus 事件总线

1. 作用

非父子组件之间,进行简易消息传递。(复杂场景→ Vuex)

2. 步骤

  1. 创建一个都能访问的事件总线(空 Vue 实例)

    import Vue from 'vue'
      const Bus = new Vue()
      export default Bus
  2. A 组件(接受方),监听 Bus 的 $on 事件

    created () {Bus.$on('sendMsg', (msg) => {this.msg = msg})
      }
  3. B 组件(发送方),触发 Bus 的 $emit 事件

    Bus.$emit('sendMsg', '这是一个消息')

3. 代码示例

新建 EventBus.js,实例化一个新组件实例并向外暴露,作为兄弟组件传值的媒介

import Vue from 'vue'
  const Bus  =  new Vue()
  export default Bus

BaseA.vue(接收方)





BaseB.vue(发送方)





App.vue





七、非父子通信 -- provide&inject

1. 作用

跨层级共享数据,不只是父子之间,也可以是祖父与孙子之间,曾祖父与重孙之间......

2. 场景

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

3. 语法

  1. 父组件 provide 提供数据

export default {provide () {
      return {
         // 普通类型【非响应式】color: this.color, 
         // 复杂类型【响应式】userInfo: this.userInfo, 
      }
    }
  }

2. 子 / 孙组件 inject 获取数据

export default {inject: ['color','userInfo'],
    created () {console.log(this.color, this.userInfo)
    }
  }

4. 完整实例

爷组件





 父组件





孙组件


 


实现效果如下图

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

对比一下前后差异:无论点击多少次,孙组件中的诞生于 year 字段永远都是 1995 并不会发生变化,通过 方式 1、方式 2、方式 4 传值是可以响应的。

正如官网所提到的:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的

另一种情况:在孙组件中修改祖组件传递过来的值(方式 1、方式 4),发现对应的祖组件中的值也发生了变化:

爷组件





父组件不变

孙组件


 


【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

 【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

5. 总结

慎用 provide / inject

既然 provide/inject 如此好用,那么,为什么 Vue 官方还要推荐我们使用 Vuex,而不是用原生的 API 呢?

答:前面提到过,Vuex 和 provide/inject 最大的区别:Vuex 中的全局状态的每次修改是可以追踪回溯的,而 provide/inject 中变量的修改是无法控制的。换句话说,不知道是哪个组件修改了这个全局状态。

Vue 的设计理念借鉴了 React 中的单向数据流原则(虽然有 sync 这种破坏单向数据流的家伙),而 provide/inject 明显破坏了单向数据流原则。试想,如果有多个后代组件同时依赖于一个祖先组件提供的状态,那么只要有一个组件修改了该状态,那么所有组件都会受到影响。这一方面增加了耦合度,另一方面,使得数据变化不可控。如果在多人协作开发中,这将成为一个噩梦。

在这里,总结了使用 provide/inject 做全局状态管理的原则:

多人协作时,做好作用域隔离;
尽量使用一次性数据作为全局状态

一层嵌套的父子组件可以使用 props 来传值,props 本身就是有相应性的。
根据自身代码选择合适的传值方式,并不一定非要用 provide/inject 的传值。

【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

🚀 个人简介:6 年开发经验,现任职某国企前端负责人,分享前端相关技术与工作常见问题~
💟 作    者:前端菜鸟的自我修养❣️
📝 专    栏:vue 从基础到起飞
🌈 若有帮助,还请 关注➕点赞➕收藏,不行的话我再努努力💪💪💪

更多专栏订阅推荐:

👍 前端工程搭建
💕 JavaScript 深入研究

原文地址: 【前端 --Vue】组件之间的多种通信方式,一文彻底搞懂组件通信!

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-07发表,共计5875字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)