vue-2 组件传值

组件关系分类

  1. 父子关系
  2. 非父子关系
    在这里插入图片描述

父子通信流程

在这里插入图片描述

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

  1. 给子组件以添加属性的方式传值
  2. 子组件内部通过 props 接收
  3. 模板中直接使用 props 接收的值

在这里插入图片描述
父组件 Parent.vue

<template>
  <div class="parent" style="border: 3px solid #f60202;text-align: center">
    <span>我是 父 组件</span>
    <!-- 1.给组件标签,添加属性方式 赋值 -->
    <div style="text-align: center">
      <Son :title="sonTitle"></Son>
    </div>
  </div>
</template>

<script>
import Son from '@/pages/test/Son.vue'
export default {
  name: 'Parent',
  data() {
    return {
      sonTitle: '父组件传给子组件',
    }
  },
  components: {
    Son,
  },
}
</script>

<style scoped>
.parent {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  height: 300px;
  width: 700px;
}
</style>

子组件 Son.vue

<template>
  <div class="son" style="border:3px solid #000">
    <!-- 3.直接使用 props 的值 -->
    我是 子 组件-- {{title}}
  </div>
</template>

<script>
export default {
  name: 'Son',
  // 2.通过 props 来接收
    props: {
    title: {
      type: String,
      require: true
    }
  }
}
</script>

<style scoped>
.son {
  height: 200px;
  width: 300px;
  margin-left: calc((700px - 300px)/2);
  margin-top: calc((300px - 200px)/2);
  float: left;
}

</style>

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

  1. $emit 触发事件,给父组件发送消息通知
  2. 父组件监听$emit 触发的事件
  3. 提供处理函数,在函数的性参中获取传过来的参数

在这里插入图片描述

代码省略样式

子组件 Son.vue

<template>
  <div class="son" style="border:3px solid #000">
    <!-- 3.直接使用 props 的值 -->
    我是 子 组件-- {{title}}<br/>
    <button @click="changeFu">修改title</button>
  </div>
</template>

<script>
export default {
  name: 'Son',
  methods: {
    changeFu() {
      // 通过this.$emit向父组件发送通知 名字要保持一致 参数一事件,参数二:参数
      this.$emit('changeTitle','newtitle')
    }
  },
  // 通过 props 来接收
  props: {
    title: {
      type: String,
      require: true
    }
  }
}
</script>

父组件 Parent.vue

<template>
  <div class="parent" style="border: 3px solid #f60202;text-align: center">
    <span>我是 父 组件</span>
    <!-- 1.给组件标签,添加属性方式 赋值 -->
    <div style="text-align: center">
      <Son :title="sonTitle" @changeTitle="handleChange"></Son>
    </div>
  </div>
</template>

<script>
import Son from '@/pages/test/Son.vue'

export default {
  name: 'Parent',
  data() {
    return {
      sonTitle: '父组件传给子组件',
    }
  },
  methods: {
    // 提供处理函数,提供逻辑
    handleChange(newTitle) {
      this.sonTitle = newTitle
    }
  },
  components: {
    Son,
  },
}
</script>

props 示例

<script>
  export default {
    // 完整写法(类型、默认值、非空、自定义校验)
    props: {
      w: {
        type: Number,
        required: true,
        default: 0,
        validator(val) {
          // console.log(val)
          if (val >= 100 || val <= 0) {
            console.error('传入的范围必须是 0-100 之间')
            return false
          } else {
            return true
          }
        },
      },
    },
  }
</script>
  • default 和 required 一般不同时写(因为当时必填项时,肯定是有值的)
  • default后面如果是简单类型的值,可以直接写默认值。如果是复杂类型的值,则需要以函数的形式 return 一个默认值

props & data、单向数据流

共同点:都可以给组件提供数据。
区别:data 的数据是自己的 → 随便改;prop 的数据是外部的 → 不能直接改,要遵循 单向数据流。
单向数据流:父级 props 的数据更新,会向下流动,影响子组件。这个数据流动是单向的。


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

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

步骤

  1. 创建一个都能访问的事件总线 (空 Vue 实例):
import Vue from 'vue'
const Bus = new Vue()
export default Bus
  1. A 组件(接受方),监听 Bus 的 $on 事件:
created () {
    Bus.$on('sendMsg', (msg) => {
      this.msg = msg
    })
  }
  1. B 组件(发送方),触发 Bus 的$emit 事件:
Bus.$emit('sendMsg', '这是一个消息')

在这里插入图片描述

代码示例

新建 EventBus.js

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

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

新建 BaseA.vue(接收方)

<template>
  <div class="base-a">
    我是 A 组件(接受方)
    <p>{{msg}}</p>
  </div>
</template>
<script>
import Bus from '@/pages/test/EventBus'
export default {
  data() {
    return {
      msg: '',
    }
  },
  created() {
    Bus.$on('sendMsg', (msg) => {
      this.msg = msg
    })
  },
}
</script>
<style scoped>
.base-a {
  width: 200px;
  height: 200px;
  border: 3px solid #000;
  border-radius: 3px;
  margin: 10px;
}
</style>

新建 BaseB.vue(发送方)

<template>
  <div class="base-b">
    <div>我是 B 组件(发布方)</div>
    <button @click="sendMsgFn">发送消息</button>
  </div>
</template>

<script>
import Bus from '@/pages/test/EventBus'
export default {
  methods: {
    sendMsgFn() {
      Bus.$emit('sendMsg', '今天天气不错,适合旅游')
    },
  },
}
</script>

<style scoped>
.base-b {
  width: 200px;
  height: 200px;
  border: 3px solid #000;
  border-radius: 3px;
  margin: 10px;
}
</style>

App.vue

<template>
  <div class="app">
    <BaseA></BaseA>
    <BaseB></BaseB>
  </div>
</template>
<script>
import BaseA from "@/pages/test/BaseA.vue";
import BaseB from "@/pages/test/BaseB.vue";

export default {
  components: {BaseB, BaseA}
}
</script>

非父子通信 — provide & inject

作用

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

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)
    }
  }

在这里插入图片描述

传递方式

export default {
  data(){
    return{
      obj:{
        name:'JavaScript',
      },
      developer:'布兰登·艾奇',
      year:1995,
      update:'2021 年 06 月',
    }
  },
  provide(){
    return {
      obj: this.obj, // 方式 1.传入一个可监听的对象
      developerFn:() => this.developer, // 方式 2.通过 computed 来计算注入的值
      year: this.year, // 方式 3.直接传值
      app: this, // 方式 4. 提供祖先组件的实例 缺点:实例上挂载很多没有必要的东西 比如:props,methods。
    }
  }
}

注意

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

在孙组件中修改祖组件传递过来的值(方式 1、方式 4),发现对应的祖组件中的值也发生了变化。查看目录爷爷组件一,父组件一,孙组件一

代码示例

爷爷组件 Grandpa.vue

<template>
  <div style="border: #fb0707 3px solid ">
    <button @click="changeMsg">祖组件触发</button>
    <h3>祖组件</h3>
    <Parent></Parent>
  </div>
</template>

<script>
import Parent from '@/pages/test/Parent.vue';
export default {
  data(){
    return{
      obj:{
        name:'JavaScript',
      },
      developer:'布兰登·艾奇',
      year:1995,
      update:'2021 年 06 月',
    }
  },
  provide(){
    return {
      obj: this.obj, // 方式 1.传入一个可监听的对象
      developerFn:() => this.developer, // 方式 2.通过 computed 来计算注入的值
      year: this.year, // 方式 3.直接传值
      app: this, // 方式 4. 提供祖先组件的实例 缺点:实例上挂载很多没有必要的东西 比如:props,methods。
    }
  },
  components: {
    Parent,
  },
  methods:{
    changeMsg(){
      this.obj.name = 'Vue';
      this.developer = '尤雨溪';
      this.year = 2014;
      this.update = '2021 年 6 月 7 日';
    },
  },
}
</script>

父组件 Parent.vue

<template>
  <div class="wrap" style="border: #0759fb 3px solid ">
    <h4>父组件(只做中转)</h4>
    <Son/>
  </div>
</template>

<script>
import Son from '@/pages/test/Son.vue';
export default {
  components:{
    Son,
  },
}
</script>

孙组件 Son.vue

<template>
  <div style="border: #605d5d 3px solid ">
    <h5>孙组件</h5>
    <span>名称:{{obj.name}}</span> |
    <span>作者:{{developer}}</span> |
    <span>诞生于:{{year}}</span> |
    <span>最后更新于:{{this.app.update}}</span>
  </div>
</template>

<script>
export default {
  computed:{
    developer(){
      return this.developerFn()
    }
  },
  inject:['obj','developerFn','year','app'],
}
</script>

爷爷组件一 Grandpa.vue

<template>
  <div style="border: #f60202 3px solid ">
    <h1>祖组件</h1>
    <span>名称:{{obj.name}}</span> |
    <span>最后更新于:{{update}}</span>
    <parent></parent>
  </div>
</template>

<script>
import parent from '@/pages/test/Parent.vue';
export default {
  data(){
    return{
      obj: {
        name: 'JavaScript',
      },
      update: '2021 年 06 月',
    }
  },
  provide() {
    return {
      obj: this.obj,
      app: this,
    }
  },
  components: {
    parent,
  },
}
</script>

父组件一 Parent.vue

不变

孙组件一 Son.vue

<template>
  <div style="border: #656567 3px solid ">
    <button @click="changeMsg">孙组件触发</button>
    <h3>孙组件</h3>
    <span>名称:{{obj.name}}</span> |
    <span>最后更新于:{{this.app.update}}</span>
  </div>
</template>

<script>
export default {
  inject:['obj','app'],
  methods: {
    changeMsg(){
      this.obj.name = 'React';
      this.app.update = '2020 年 10 月';
    }
  },
}
</script>

在这里插入图片描述

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/696495.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣 T62 不同路径

题目 连接 思路 思路1 &#xff1a; BFS爆搜 class Solution { public:queue<pair<int,int>>q;int uniquePaths(int m, int n) {q.push({1,1}); // 起始位置vector<pair<int, int>> actions;actions.push_back({0, 1}); // 向下actions.push_bac…

论文中eps格式图片制作

在提交论文终稿时&#xff0c;有时需要提交论文中图片的eps格式&#xff0c;这里记录一下eps格式图片制作的过程&#xff0c;方便以后查阅。 论文中eps格式图片制作 PPT绘制的图片转换为eps格式使用代码生成的图片Latex中显示的图片大小跟Ai中设定画板的大小不一致 PPT绘制的图…

ABB机械人模型下载

可以下载不同格式的 https://new.abb.com/products/robotics/zh/robots/articulated-robots/irb-6700 step的打开各部件是分开的&#xff0c;没有装配在一起&#xff0c;打开看单个零件时&#xff0c;我们会发现其各零件是有装配的定位关系的。 新建一个装配环境&#xff0c;点…

ctfshow-web入门-命令执行(web53-web55)

目录 1、web53 2、web54 3、web55 1、web53 这里的代码有点不一样&#xff0c;说一下这两种的区别&#xff1a; &#xff08;1&#xff09;直接执行 system($c); system($c);这种方式会直接执行命令 $c 并将命令的输出直接发送到标准输出&#xff08;通常是浏览器&#xff…

基于机器学习和深度学习的NASA涡扇发动机剩余使用寿命预测(C-MAPSS数据集,Python代码,ipynb 文件)

以美国航空航天局提供的航空涡扇发动机退化数据集为研究对象&#xff0c;该数据集包含多台发动机从启动到失效期间多个运行周期的多源传感器时序状态监测数据&#xff0c;它们共同表征了发动机的性能退化情况。为减小计算成本&#xff0c;需要对原始多源传感器监测数据进行数据…

软件测试--Mysql快速入门

文章目录 软件测试-mysql快速入门sql主要划分mysql常用的数据类型sql基本操作常用字段的约束&#xff1a;连接查询mysql内置函数存储过程视图事务索引 软件测试-mysql快速入门 sql主要划分 sql语言主要分为&#xff1a; DQL&#xff1a;数据查询语言&#xff0c;用于对数据进…

SpringBoot中实现一个通用Excel导出功能

SpringBoot中实现一个通用Excel导出功能 文章目录 SpringBoot中实现一个通用Excel导出功能这个导出功能的特色看效果代码解析1、依赖2、Excel 入参(ExcelExportRequest)3、Excel 出参(ExcelExportResponse)4、ExcelExportField5、ExcelExportUtils 工具类6、ExcelHead 头部…

鸿蒙开发接口安全:【@ohos.userIAM.userAuth (用户认证)】

用户认证 说明&#xff1a; 本模块首批接口从API version 6开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import userIAM_userAuth from ohos.userIAM.userAuth;完整示例 // API version 6 import userIAM_userAuth from ohos.use…

AI全栈工程师的新舞台:Coze(扣子)

前言 在当前科技飞速发展的背景下&#xff0c;Coze作为一款引领潮流的AI应用平台&#xff0c;正以破竹之势重塑着我们对于智能应用的认知。Coze不仅仅是一个工具&#xff0c;它是一个集合了前沿AI技术、高效开发环境与创意无限的应用生态于一体的创新平台&#xff0c;旨在让每…

RabbitMQ-工作模式(Topics模式RPC模式Publisher Confirms模式)

文章目录 Topics模式topic代码示例 RPC模式客户端界面回调队列关联ID总结RPC代码示例 Publisher Confirms模式概述在通道上启用发布者确认单独发布消息批量发布消息异步处理发布者确认总结总体代码示例 更多相关内容可查看 Topics模式 在Topics中&#xff0c;发送的消息不能具…

QT 信号和槽 信号关联到信号示例 信号除了可以绑定槽以外,信号还可以绑定信号

信号除了可以关联到槽函数&#xff0c;还可以关联到类型匹配的信号&#xff0c;实现信号的接力触发。上个示例中因为 clicked 信号没有参数&#xff0c;而 SendMsg 信号有参数&#xff0c;所以不方便直接关联。本小节示范一个信号到信号的关联&#xff0c;将按钮的 clicked 信号…

---java 抽象类 和 接口---

抽象类 再面向对对象的语言中&#xff0c;所以的对象都是通过类来描述的&#xff0c;但如果这个类无法准确的描述对象的 话&#xff0c;那么就可以把这个类设置为抽象类。 实例 这里用到abstract修饰&#xff0c;表示这个类或方法是抽象方法 因为会重写motifs里的show方法…

【已解决】FileNotFoundError: [Errno 3] No such file or directory: ‘xxx‘

&#x1f60e; 作者介绍&#xff1a;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff0c;视频号&#xff1a;AI-行者Sun &#x1f388; 本文专栏&#xff1a;本文收录于《AI实战中的各种bug…

游戏服务器工程实践一:百万级同时在线的全区全服游戏

我应该有资格写这篇文章&#xff0c;因为亲手设计过可以支撑百万级同时在线的全区全服类型的游戏服务器架构。 若干年前我在某公司任职时&#xff0c;参与研发过一款休闲类型的游戏&#xff0c;由 penguin 厂独代。研发的时候&#xff0c;p 厂要求我们的游戏服务器要能支撑百万…

如何自我认同?是否需要执着于社会性认同?

一、自我认同与社会性认同 自我认同与社会性认同是两个相关但又有所区别的概念&#xff0c;它们分别反映了个体在内心深处对自身价值的认知&#xff0c;以及外界&#xff08;尤其是社会&#xff09;对个体价值的评价与接纳。 自我认同 自我认同是指个体基于自身的价值观、能…

【C语言】青蛙跳台阶问题 - 递归算法(一种思路,针对三种不同的情况)

文章目录 1. 前言2. 题目和分析2.1 代码实现2.2 反思 (重点) 3.题目二&#xff08;变式&#xff09;3.1 分析3.2 代码实现 4. 题目三&#xff08;变式&#xff09;4.1 分析4.2 代码实现 1. 前言 相信大家看到青蛙跳台阶问题时&#xff0c;第一时间就会想到递归。那你知道为什么…

暴雨推出X705显示器:23.8英寸100Hz IPS屏

IT资讯 6月 7 日消息&#xff0c;日前&#xff0c;暴雨发布了一款 23.8 英寸 IPS 显示器&#xff0c;直屏、支持 100Hz 刷新率。 据官方介绍&#xff0c;X705 显示器分辨率为 19201080&#xff0c;亮度为 300 尼特&#xff08;典型值&#xff09;&#xff0c;对比度 1000:1&…

Junit(Java单元测试)

目录 配置文件 注解 Test 标注测试方法 BeforeAll 和 AfterAll 标注在测试之前和之后执行的方法 BeforeEach 和 AfterEach 标注在每条测试之前和之后执行的方法 TestMethodOrder 和 Order(优先级) 标注测试方法的执行顺序 ParameterizedTest 将测试方法参数化 ValueSou…

【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现(附源码)(下篇)

作者&#xff1a;后端小肥肠 上篇&#xff1a;【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现&#xff08;上篇&#xff09;_spring security activiti7-CSDN博客 目录 1.前言 2. 核心代码 2.1. 流程定义模型管理 2.1.1. 新增流程定义模型数据 …

转让北京劳务分包地基基础施工资质条件和流程

地基基础资质转让流程是怎样的?对于企业来说&#xff0c;资质证书不仅是实力的证明&#xff0c;更是获得工程承包的前提。而在有了资质证书后&#xff0c;企业才可以安心的准备工程投标&#xff0c;进而在工程竣工后获得收益。而对于从事地基基础工程施工的企业&#xff0c;需…