Vue组件之间传值

聊一聊vue里面组件之间的传值

首先总结一下vue里面传值的几种关系:
在这里插入图片描述
如上图所示, A与B、A与C、B与D、C与F组件之间是父子关系; B与C之间是兄弟关系;A与D、A与E之间是隔代关系; D与F是堂兄关系,针对以上关系 我们把组件之间传值归类为:
1.父子组件之间的通讯
2.非父子组件之间的通讯(兄弟组件 隔代关系组件)

vue里面组件通许的方式:

  1. props/$emit
  2. $children / $parent
  3. ref / refs
  4. provide / reject
  5. eventBus
  6. $attrs / $linteners
  7. vuex
  8. localStorage / sessionStorage

1.父组件向子组件传值

<template><div class="section"><com-article :articles="articleList"></com-article></div>
</template>
<script>
import comArticle from './test/article.vue'
export default {name: 'HelloWorld',components: { comArticle },data() {return { articleList: ['1', '2', '3'] }}
}
</script><template><div><span v-for="(item, index) in articles" :key="index">{{ item }}</span></div><script>export default {props: ['articles']}
</script>

2.子组件向父组件传值

<template><div class="section"><com-article :articles="articleList" @onEmitIndex="onEmitIndex"></com-article><p>{{ currentIndex }}</p></div>
</template>
<script>
import comArticle from './test/article.vue'
export default {name: 'HelloWorld',components: { comArticle },data() {return { currentIndex: -1, articleList: ['小姐姐', '小妹妹', '小富婆'] }},methods: {onEmitIndex(idx) {this.currentIndex = idx}}
}
</script>// prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop
只读,不可被修改,所有修改都会失效并警告。<template><div><div v-for="(item, index) in articles" :key="index" @click="emitIndex(index)">{{ item }}</div></div>
</template><script>
export default {props: ['articles'],methods: {emitIndex(index) {this.$emit('onEmitIndex', index)}}
}
</script>

二. $children / $parent 直接简单点写法:

 this.$parentthis.$children

这种方式是直接通过children 或者parent获取组件上的所有对象实例,并且他还是一个数组,我们一般要获取需要这么写
this.$children[0].age,通过索引获取到自己想要的子组件,当子组件比较多的时候,如果后期某个子组件删除了或者新增,对应的索引有可能会发生变化,既不利于维护,所以在实际开发中用的比较少。
同样的this. $parent获取父组件的所有实例对象,当涉及到公共子组件的时候,定义的名称可能耦合性比较高,如果以这种方式去修改父组件的状态,很容易出问题,甚至调试都很不方便,所以也一般用的比较少。

3. ref / refs
ref:如果在普通的 DOM 元素上使用,引用指向的就是DOM 元素,可以操作dom元素的方法,如果用在子组件上,引用就指向组件实例,可以通过实例直接调用子组件的方法或数据

<template><span>{{name}}</span>
</template>
<script>
export default {data() {return {name: 'xxxx'}},
}
</script><template><component-a ref="comA"></component-a><span ref="spanRef">1234</span><a-button type="primary" @click="handleClick">xx</a-button>
</template>
<script>
export default {methods: {handleClick(){console.log(this.$refs.spanRef.innerHtml); // 1234const comA = this.$refs.comA;console.log(comA.name)}},
}
</script>

4.provide / reject

5.eventBus
eventBus可以作为全局组件通信(任意的两个组件,没有任何关联的组件),可以直接进行交流的通讯方案,eventBus通常用来做全局范围内通信的一个常用方案,非常灵活 使用简单而且很轻
在vue2里面的使用:

import Vue from 'vue'
// main.js 中// 第一种定义方式
Vue.prototype.$eventBus = new Vue()// 第二种定义方式
window.eventBus = new Vue();**触发事件:**
// params 多个参数
this.$eventBus.$emit('eventName', param1,param2,...)//使用方式二定义时
eventBus.$emit('eventName', param1,param2,...)**监听事件**
//使用方式一定义时
this.$eventBus.$on('eventName', (param1,param2,...)=>{//需要执行 逻辑代码// params 多个参数
})//使用方式二定义时
eventBus.$on('eventName', (param1,param2,...)=>{//需要执行 逻辑代码
})**移除事件,在开发过程中,当离开当前页面时要取消坚挺,避免事件被反复出发,和造成内存泄漏**
//使用方式一定义时
this.$eventBus.$off('eventName');//使用方式二定义时
eventBus.$off('eventName');

EventBus的原理是什么? 直接上代码

class MyEventBus {constructor() {// 存储所有事件对应的回调的对应关系/*** key : [ callback, callback ]*/this.items = {};}// 监听$on(eventName, callback) {if (!this.items[eventName]) {//一个事件可能有多个监听者this.items[eventName] = [];}this.items[eventName].push(callback)// 简化版写法 等同于上面// (this.items[eventName] ||= []).push(callback)}// 触发监听$emit(eventName, ...args) {if (!this.items[eventName]) return;this.items[eventName].forEach(ca => ca(...args))}// 去掉监听$off(eventName) {this.items[eventName] = []}
}
export default new MyEventBus();

Vue3种移除了$on $off等自带自定义事件的相关方法,因此在vue3中使用mitt来代替eventBus

    //在utils目录下,新建 mitt.js 文件,写入下面代码进行封装import mitt from 'mitt'const emitter =new mitt()export default emitter// 在使用中直接引入import emitter from '../api/mitt'emitter.on('foo', e => console.log(e) )  //emitteremitter.emit('foo', 'emitter')// 用法 引入封装好的mitt即可直接使用mitt,但需要注意:注册事件最好在钩子onMounted中进行,并且注册的事件需要在onUnmounted钩子中移除。如果不移除同样有可能会造成反复调用,和内存泄漏等问题// 引入 mittimport emitter from '../api/mitt'// 注册emitter.on('eventName', function(e) {console.log(e)})// 调用emitter.emit('eventName', 'emitter')// 移除emitter.off('eventName')

5. $attrs / $linteners

$attrs:用于多层次组件传递参数(组件标签的attribute,class和style除外),爷爷辈组件向孙子辈组件传递参数(注:参数不能被父辈prop识别,一旦被父辈prop识别且获取,则孙子辈组件不能获取到该参数) 并且 v-bind不能被简写

$listeners:用于多层次组件传递事件监听器,爷爷辈组件向父辈、孙子辈、曾孙子辈……组件传递事件(与 $attrs 不同,不存在半路被拦截的情况)v-on 不能用简写 @,虽然不报错,但是也不生效

<template><div>GrandFather:<index1 :dataMessage="dataMessage" :dataCode="dataCode" :dataList="dataList" :grendClick="grendClick"@hancleClick="handleClick" @handleSelect="handleSelect" aaa="this is a undefiend" /></div>
</template><script>
import Index1 from "./index1";
export default {props: { dataStatus: Number },components: { Index1 },data() {return {a: 0,dataMessage: 1234,dataCode: "400",dataList: [1, 2, 3, 4, 5],};},methods: {handleClick() {console.log(1234);},handleSelect() {console.log(456);},grendClick() {console.log("grendClick");},},
};
</script><script>
import Index2 from './index2.vue';
export default {inheritAttrs: false,components: { Index2},props: {dataMessage: {default: 0,type: Number},grendClick: {default: () => {return Function}}},data() { return {  adus: '12345'  } },created() {// 这个从一级组件的dataMessage被当前页截取了。console.log(this.dataMessage, 'dataMessage');},methods: {handleClickB() {console.log('this is B');this.grendClick()},},
}
</script><template><div><span>GrandSon</span><a-button type="primary" @click="handleClickC">GrandSon</a-button><span ref="spanRef">1234</span></div>
</template><script>
export default {inheritAttrs: false,methods: {handleClickC() {console.log(this.$attrs, 'attrs'); // 从最上级带过来的变量console.log(this.$listeners, 'listeners'); // 从最上级带过来方法},},
}
</script>

关于Vue的inheritAttrs的理解:
vue官网对于inheritAttrs的属性解释:默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。
如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false。

直接看效果: 当设置为true,默认是为true的
在这里插入图片描述

当设置为false时后:这也算的上是一点点小优化策略吧
在这里插入图片描述
7.localStorage / sessionStorage
这个我们用的应该是比较多的,我们在vue里面用的比较多的Vul-ls

import Vue from 'vue'
import Storage from 'vue-ls'// vue-ls 的配置
const storageOptions = {namespace: 'vue_',   // key 键的前缀(随便起)name: 'ls',          // 变量名称(随便起) 使用方式:Vue.变量名称 或 this.$变量名称storage: 'local'     // 作用范围:local、session、memory
}Vue.use(Storage, storageOptions)
就不做具体的操作了

浏览器缓存里面有个可以监听缓存变化的方法:废话不多说 上代码

export const resetSetItem = (key: string, newVal: string) => {if (key === 'reportcenterList') {// 创建一个StorageEvent事件const newStorageEvent = document.createEvent('StorageEvent')const storage = {setItem: function (k, val) {sessionStorage.setItem(k, val)// 初始化创建的事件newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null)// 派发对象window.dispatchEvent(newStorageEvent)}}return storage.setItem(key, newVal)}
}// 调用resetSetItem('reportcenterList', JSON.stringify(val))console.log('监听到数据变化')const reportcenterList = sessionStorage.getItem('reportcenterList') || ''

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

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

相关文章

Redis 缓存穿透击穿和雪崩

一、说明 Redis 缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要害的问题&#xff0c;就是数据的一致性问题&#xff0c;从严格意义上讲&#xff0c;这个问题无解。如果对…

Nginx基础+高级(2022版):待更新

1. 文章说明 说明&#xff1a;目前讲的是第一部分nginx核心技术篇&#xff0c;后需篇章会以第一部分为核心技术篇为基础来展开深度讲解&#xff0c;详情关注后续课程的发布。 2. 介绍和准备环境 2.1 介绍 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xf…

动态维护直径 || 动态维护树上路径 || 涉及LCA点转序列 || 对欧拉环游序用数据结构维护:1192B

https://www.luogu.com.cn/problem/CF1192B 对于直径的求法&#xff0c;常用dp或两次dfs&#xff0c;但如果要动态维护似乎都不太方面&#xff0c;那么可以维护树上路径最大值。 树上路径为&#xff1a; d e p u d e p v − 2 d e p l c a ( u , v ) dep_udep_v-2\times de…

iPhone 15 Pro展示设计:7项全新变化呈现

我们不应该再等iPhone 15 Pro在苹果9月12日的“Wonderlust”活动上发布了&#xff0c;而且可能会有很多升级。有传言称&#xff0c;iPhone 15 Pro将是自iPhone X以来最大的飞跃&#xff0c;这要归功于大量的新变化&#xff0c;从带有更薄边框的新钛框架到顶级A17仿生芯片和动作…

[管理与领导-70]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 个人的能力盘点

目录 前言&#xff1a; 一、什么是能力&#xff08;What&#xff09; 1.1 什么是能力 1.2 能力类型 1.3 技能矩阵 二、优势与劣势模型 2.1 优势与劣势 2.2 SWOT模型 三、人才结构模型 3.1 广度优先&#xff1a;一字型/全面型人才 3.2 深度优先&#xff1a;I型人才、…

Django框架中使用drf框架开发

一、drf框架特点&#xff1a; 全称 Django REST framework 两大部分&#xff1a;序列化/反序列化 和 增删改查序列化&#xff1a;把数据库数据提取出来变成python常用格式的过程&#xff0c;例如转成json格式这种反序列化&#xff1a;把数据写入到数据库的过程&#xff0c…

浅谈一下酒吧和酒馆的不同

相信有很多朋友还不怎么清楚酒吧和酒馆的区别是什么&#xff0c;这里为大家简单介绍一下两者的不同&#xff0c;个人见解&#xff0c;如有错漏&#xff0c;欢迎指出。一、首先是他们的经营范围不同酒馆经营通常包含酒水和餐饮&#xff0c;适合朋友聚会或者是和商业伙伴聊天。而…

QLoRA:量化LLM的高效微调策略与实践

如果你对这篇文章感兴趣&#xff0c;而且你想要了解更多关于AI领域的实战技巧&#xff0c;可以关注「技术狂潮AI」公众号。在这里&#xff0c;你可以看到最新最热的AIGC领域的干货文章和案例实战教程。 一、前言 在大型语言模型&#xff08;LLM&#xff09;领域&#xff0c;微…

(位运算) 剑指 Offer 15. 二进制中1的个数 ——【Leetcode每日一题】

❓ 剑指 Offer 15. 二进制中1的个数 难度&#xff1a;简单 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为 汉明重量).&#xff09;。 提示&#xff…

计算机网络自顶向下-web页面请求历程

1. 准备: DHCP、 UDP、 IP 和以太网 假定 Bob 启动他的便携机&#xff0c;然后将其用一根以太网电缆连接到学校的以太网交换机 &#xff0c; 交换机与学校的路由器相连。学校的路由器与一个 ISP 连接&#xff0c; 本例中 ISP 为 comcast.net &#xff0c;为学校提供了 DNS 服务…

开发前期准备工作

开发前期准备工作 文章目录 开发前期准备工作0 代码规范0.1 强制0.2 推荐0.3 参考dao&#xff1a;跟数据库打交道service&#xff1a;业务层&#xff0c;人类思维解决controller&#xff1a;抽象化 0.4 注释规范0.5 日志规范0.6 专有名词0.7 控制层统一异常统一结构体控制层提示…

java线程和go协程

一、线程的实现 线程的实现方式主要有三种&#xff1a;内核线程实现、用户线程实现、用户线程加轻量级进程混合实现。因为自己只对java的线程比较熟悉一点&#xff0c;所以主要针对java线程和go的协程之间进行一个对比。 线程模型主要有三种&#xff1a;1、内核级别线程&#…

Unittest自动化测试框架vs Pytest自动化测试框架

引言   前面一篇文章Python单元测试框架介绍已经介绍了python单元测试框架&#xff0c;大家平时经常使用的是unittest&#xff0c;因为它比较基础&#xff0c;并且可以进行二次开发&#xff0c;如果你的开发水平很高&#xff0c;集成开发自动化测试平台也是可以的。而这篇文章…

如何培养潜在客户?看完这篇你就懂了

图片来源于&#xff1a;SaleSmartly官网 有效的潜在客户培育策略将帮助您将更多潜在客户转化为付费客户。 但是&#xff0c;这并不总是那么容易——您必须与其他公司争夺受众的注意力&#xff0c;并向您的领导证明为什么值得投资您的产品或服务。在本文中&#xff0c;我将向您展…

STM32 RTC实验

RTC时钟简介 STM32F103的实时时钟&#xff08;RTC&#xff09;是一个独立的定时器。 STM32的RTC模块拥有一组连续计数的计数器&#xff0c;在相对应的软件配置下&#xff0c;可提供时钟日历的功能。 修改计数器的值可以重新设置系统的当前时间和日期。 RTC模块和时钟配置系统…

iKeyPrime完美解4G信号,可以登录iCloud,有消息通知,支持最新iOS16.6。

iKeyPrime是一款绕过激活锁界面的解锁工具&#xff0c;可以激活所有iPhone苹果手机&#xff0c;二网/三网恢复信号&#xff0c;并且支持插卡接打电话、收发短信、4G流量上网&#xff0c;支持iCloud登录&#xff0c;有消息通知&#xff0c;支持iPhone5S~X的所有型号&#xff0c;…

精益制造、质量管控,盛虹百世慧共同启动MOM(制造运营管理)

百世慧科技依托在电池智能制造行业中的丰富经验&#xff0c;与盛虹动能达成合作&#xff0c;为其提供MOM制造运营管理平台&#xff0c;并以此为起点&#xff0c;全面提升盛虹动能的制造管理水平与运营体系。 行业困境 中国动力电池已然发展为全球最大的电池产业&#xff0c;但…

[ROS]yolov7部署ROS

Yolov7是一种基于PyTorch深度学习框架的目标检测算法&#xff0c;具有高精度和快速的特点&#xff0c;被广泛应用于机器人领域。将Yolov7部署到ROS中可以方便地实现机器人对环境的感知和理解。 在部署Yolov7到ROS之前&#xff0c;需要准备以下环境和工具&#xff1a; Ubuntu …

Netty—FuturePromise

Netty—Future&Promise 一、JDK原生 Future二、Netty包下的 Future三、Promise1、使用Promise同步获取结果2、使用Promise异步获取结果.3、使用Promise同步获取异常 - sync & get4、使用Promise同步获取异常 - await5、使用Promise异步获取异常 在异步处理时&#xff0…

Img标签的src地址自动拼接本地域名(localhost:8080)导致图片不显示问题

摘要&#xff1a;做Vueelement ui项目的时候&#xff0c;发现使用element ui的upload上传图片时&#xff0c;不显示的问题。我项目的图片是上传到七牛云&#xff0c;长传成功后返回存储在七牛云中的地址。后面发现是因为返回的地址是外部地址&#xff0c;需要完整的URL&#xf…