vue-2 组件传值

news2024/11/26 23:41:36

组件关系分类

  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.coloradmin.cn/o/1816525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全网首发-Docker被封后的代理设置教程

最近上交、科大以及阿里的一些docker镜像&#xff0c;好像都因为不可控力导致无法访问。 所以&#xff0c;之前好多正常的一些镜像的打包都会报错&#xff1a; 比如&#xff1a; #1 [internall load build definition from Dockerfile#1transferring dockerfile:972B done#1 D…

Day 13:3072. 将元素分配到两个数组中 Ⅱ

Leetcode 3072. 将元素分配到两个数组中 Ⅱ 给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 现定义函数 greaterCount &#xff0c;使得 greaterCount(arr, val) 返回数组 arr 中** 严格大于** val 的元素数量。 你需要使用 n 次操作&#xff0c;将 nums 的所有元素分配到…

一种基于混合协作的约束多目标优化的新型多群体进化算法

A novel multi-population evolutionary algorithm based on hybrid collaboration for constrained multi-objective optimization 原文链接: https://doi.org/10.1016/j.swevo.2024.101581 Wang Q, Li Y, Hou Z, et al. A novel multi-population evolutionary algorithm bas…

网络编程(一)基本概念、TCP协议

文章目录 一、概念&#xff08;一&#xff09;网络发展阶段1. ARPAnet阶段2. TCP/IP两个协议阶段3. 网络体系结构和OSI开放系统互联模型4. TCP/IP协议簇体系结构&#xff08;1&#xff09; 应用层&#xff1a;&#xff08;2&#xff09;传输层&#xff1a;&#xff08;3&#x…

集成算法实验(Bagging策略)

Bagging模型(随机森林) Bagging&#xff1a;训练多个分类器取平均 f ( x ) 1 / M ∑ m 1 M f m ( x ) f(x)1/M\sum^M_{m1}{f_m(x)} f(x)1/M∑m1M​fm​(x) 全称&#xff1a; bootstrap aggregation&#xff08;说白了就是并行训练一堆分类器&#xff09; 最典型的代表就是随…

聚鼎科技:装饰画哪里好卖

在当代社会&#xff0c;艺术与商业的界限日益模糊&#xff0c;装饰画作为一种既能美化空间又能体现个人品味的物品&#xff0c;受到了广泛的欢迎。但许多创作者和商家常常面临一个问题&#xff1a;《装饰画哪里好卖》? 要解决这个问题&#xff0c;我们需明白市场需求的重要性。…

斜率优化详解

斜率优化 [HNOI2008] 玩具装箱 状态转移方程&#xff1a; f i m i n ( f i , f j ( s u m i i − s u m j − j − L ) 2 ) i > j f_imin(f_i,f_j(sum_ii-sum_j-j-L)^2){i>j} fi​min(fi​,fj​(sumi​i−sumj​−j−L)2)i>j 设A为 s u m i i sum_ii sumi​i&…

代码随想录算法训练营第36天(py)| 贪心 | 452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间

452. 用最少数量的箭引爆气球 力扣链接 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同…

【kubernetes】k8s集群安全机制 保姆级攻略

目录 一、认证&#xff08;Authentication&#xff09; Kubernetes 作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介&#xff0c; 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 A…

CCNA 0基础入门

OSI & TCP/IP OSI参考模型 TCP/IP协议 应用层 ------↓表示层 ------>应用层会话层 ------↑传输层 ------>传输层网络层 ------>网络互联层链路层 ------>网络接口层物理层 ------>↑ 物理层 传输的信号以及网线以及接线 主要作用是产生并检测电…

怎么修改Visual Studio Code中现在github账号

git config --global user.name “你的用户名” git config --global user.email “你的邮箱” git config --global --list git push -u origin your_branch_name git remote add origin

手部出现这4种症状,可能是糖尿病先兆!务必及时监测血糖

糖尿病来袭&#xff0c;手部或先知&#xff01;出现这 4 种症状&#xff0c;务必尽快监测血糖 第一&#xff0c;手指麻木感明显&#xff0c;当持续性的高血糖损害手部血管与神经末梢时&#xff0c;便会导致手指产生麻木以及刺痛之感。而且随着血糖不断升高&#xff0c;受损的血…

【QT Creator软件】解决中文乱码问题

QT Creator软件解决中文乱码问题 问题描述&#xff1a;Qtcreator安装好后打印中文在控制台输出乱码 在网上也查找了修改编辑器的默认编码为UTF-8&#xff0c;但是仍然没有任何作用&#xff0c;于是有了以下的解决方案 原因剖析&#xff1a;因为项目的编码与控制台的编码不一致…

Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件

打包与运行 window版本上制作 我们要把idea中的程序抽取出来作为一个独立的jar包 把jar包放到服务器上 服务器是长期运行的 我们就能随时访问了 在Maven的生命周期中选择package 打包功能 在资源管理器中查找 java -jar 文件名.jar java -jar 文件名.jar 但是我们在测试…

kotlin 中的字符串

一、字符类访问 1、字符串的访问跟js一样&#xff0c;可以使用索引来访问或者直接循环。 fun main() {val a: String "2024"// 方式一&#xff1a;for (item in a) {println(item) // 输出每一个字符}// 方式二&#xff1a;println("${a[0]}, ${a[1]}, ${a[2…

纯干货科普!水浸传感器品牌该怎么选?

在现代化生产过程中&#xff0c;漏水是常见的安全隐患之一。特别是机房、档案馆等高精密设备较多的场合&#xff0c;一旦没有及时解决漏水问题&#xff0c;就有可能导致线路故障、设备损坏甚至业务办理。绝大部分管理人员会选择安装水浸传感器&#xff0c;它能够帮我们及时检测…

bugku---misc---easy_nbt

1、题目描述 2、下载附件&#xff0c;解压之后得到 3、查找资料发现&#xff1a;NBT文件是Minecraft游戏数据文件&#xff0c;其中包含以命名二进制标签(NBT)格式保存的数据。这种格式用于存储大量二进制数据&#xff0c;通常包含有关Minecraft世界的信息。NBT数据通常以.dat文…

2024 全球软件研发技术大会官宣,50+专家共话软件智能新范式!

2024年的全球软件研发技术大会&#xff08;SDCon&#xff09;由CSDN和高端IT咨询与教育平台Boolan联合主办&#xff0c;将于7月4日至5日在北京威斯汀酒店举行。本次大会的主题为“大模型驱动软件智能化新范式”&#xff0c;旨在探讨大模型和开源技术的发展如何引领全球软件研发…

Xmind导入纯文本TXT方法

最近有很多同事咨询我如何在xmind直接导入纯文本txt笔记或者思维导图呢&#xff1f; 解决办法如下&#xff1a; 1.先打开xmind随便打开一个思维导图-文件-导出-marldown 2.选中导出的markdown文件。右键-打开方式-苹果系统选择文本编辑&#xff0c;Win系统选择记事本 3.按照图示…

计算机二级Access选择题考点

在Access中&#xff0c;若要使用一个字段保存多个图像、图表、文档等文件&#xff0c;应该设置的数据类型是附件。在“销售表"中有字段:单价、数量、折扣和金额。其中&#xff0c;金额单价x数量x折扣&#xff0c;在建表时应将字段"金额"的数据类型定义为计算。若…