Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Vue中 $attrs、$listeners 详解及使用

Vue中 $attrs、$listeners 详解及使用

作者头像
全栈程序员站长
发布于 2022-11-02 09:17:06
发布于 2022-11-02 09:17:06
1.6K00
代码可运行
举报
运行总次数:0
代码可运行

传送门:Vue中 子组件向父组件传值 及 .sync 修饰符 详解 传送门:Vue中 状态管理器(vuex)详解及应用场景 传送门:Vue中 事件总线(eventBus)详解及使用 传送门:Vue中 provide、inject 详解及使用

Vue中 常见的组件通信方式可分为三类
  • 父子通信
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
父向子传递数据是通过 props,子向父是通过 events($emit);
通过父链 / 子链也可以通信($parent / $children);
ref 也可以访问组件实例;
provide / inject;
$attrs/$listeners;
  • 兄弟通信
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Bus;
Vuex;
  • 跨级通信
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Bus;
Vuex;
provide / inject、
$attrs / $listeners、
1. 前言

多级组件嵌套需要传递数据时,通常使用的方法是通过 vuex。如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点杀鸡用牛刀。 Vue 2.4 版本提供了另一种方法,使用 v-bind=”$attrs”, 将父组件中不被认为 props 特性绑定的属性传入子组件中,通常配合 interitAttrs 选项一起使用。之所以要提到这两个属性,是因为两者的出现使得组件之间跨组件的通信在不依赖 vuex 和 事件总线 的情况下变得简洁,业务清晰。

首先分析以下应用场景

A 组件与 B 组件之间的通信: (父子组件)

如上图所示,A、B、C三个组件依次嵌套,按照 Vue 的开发习惯,父子组件通信可以通过以下方式实现:

  • A to B 通过 props 的方式向子组件传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现;
  • 通过设置全局 Vuex 共享状态,通过 computed 计算属性和 commit mutation 的方式实现数据的获取和更新,以达到父子组件通信的目的;
  • Vue Event Bus,使用 Vue 的实例,实现事件的监听和发布,实现组件之间的传递;

往往数据在不需要全局的情况而仅仅是父子组件通信时,使用第一种方式即可满足。

A 组件与 C 组件之间的通信: (跨多级的组件嵌套关系)

如上图,A 组件与 C 组件之间属于跨多级的组件嵌套关系,以往两者之间如需实现通信,往往通过以下方式实现:

  • 借助 B 组件的中转,从上到下 props 依次传递,从下至上 $emit 事件的传递,达到跨级组件通信的效果;
  • 借助 Vuex 的全局状态共享;
  • Vue Event Bus,使用 Vue 的实例实现事件的监听和发布,实现组件之间的传递

第一种通过 props 和 $emit 的方式,使得组件之间的业务逻辑臃肿不堪,B组件在其中仅仅充当的是一个中转站的作用; 第二种 Vuex 的方式,某些情况下似乎又有点大材小用的意味(仅仅是想实现组件之间的一个数据传递,并非数据共享的概念); 第三种情况的使用在实际的项目操作中发现,如不能实现很好的事件监听与发布的管理,往往容易导致数据流的混乱,在多人协作的项目中,不利于项目的维护;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$attrs 以及 $listeners 的出现解决的就是第一种情况的问题,B 组件在其中传递 props 以及事件的过程中,不必在写多余的代码,
仅仅是将 $attrs 以及 $listeners 向上或者向下传递即可。
2. 知识点

inheritAttrs:默认值 true,继承所有的父组件属性(除 props 的特定绑定)作为普通的HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继承特性设置 inheritAttrs: false ,但是 class 属性会继承。 (简单的说,inheritAttrs:true 继承除 props 之外的所有属性;inheritAttrs:false 只继承 class style 属性)

$attrs–继承所有的父组件属性(除了 prop 传递的属性、class 和 style ),一般用在子组件的子元素上

listeners属性,它是一个对象,里面包含了作用在这个组件上的所有监听器,你就可以配合 v-on=”listeners” 将所有的事件监听器指向这个组件的某个特定的子元素。(相当于子组件继承父组件的事件)

3. 示例

A组件(App.vue)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
<div id="app">
<!-- 此处监听了两个事件,可以在B组件或者C组件中直接触发 -->
<child1  :pchild1="child1" :pchild2="child2" :pchild3="child3" @method1="onMethod1" @method2="onMethod2"></child1>
</div>
</template>
<script>
import Child1 from "./Child1.vue";
export default { 

data() { 

return { 

child1:'1',
child2: 2,
child3:{ 

name:'child3'
}
};
},
components: { 
 Child1 },
methods: { 

onMethod1(msg1) { 

console.log(`${ 
msg1} running`);
},
onMethod2(msg2) { 

console.log(`${ 
msg2} running`);
},
},
};
</script>

B组件(Child1.vue)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
<div class="child-1">
<h2>in child1</h2>
<p>props: { 
{ 
 pchild1 }}</p>
<p>$attrs: { 
{ 
 $attrs }}</p>
<hr/>
<!-- 通过 v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
<!-- C组件中能直接触发test的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
<child2 v-bind="$attrs" v-on="$listeners"></child2>
</div>
</template>
<script>
import Child2 from "./Child2.vue";
export default { 

data() { 

return { 

child1:'child1'  
};
},
components: { 
 Child2 },
props: { 

pchild1:{ 

type:String
}
},  
inheritAttrs: false,
mounted() { 

this.$emit("method1",this.child1);
},
};
</script>

C 组件 (Child2.vue)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
<div class="child-2">
<h2>in child2:</h2>
<p>props: { 
{ 
 pChild2 }}</p>
<p>$attrs: { 
{ 
 $attrs }}</p>
<p>pchild3Name: { 
{ 
 $attrs.pchild3.name }}</p>
<hr/>
</div>
</template>
<script>
export default { 

data() { 

return { 

child2:'child2'
};
},
props: { 

pChild2:{ 

type:String,
}
},
inheritAttrs: false,
mounted() { 

this.$emit("method2",this.child2);
},
};
</script>

效果

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180722.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入浅出,带你看懂Vue组件间通信的8种方案
子组件通过$emit触发定义在父组件里面的自定义事件,他可以传两个值,第一个是自定义事件名,第二个是要传递的值。
JanYork_简昀
2022/08/29
1.3K0
深入浅出,带你看懂Vue组件间通信的8种方案
Vue 组件通信六种方法
今天继续加油学习,今天整理一下VUE中组件通信六种方式,依次介绍一下各个通信方式。嘻嘻嘻,让我们一起学起来好吧~~~come
默默的成长
2022/10/29
7150
Vue 组件通信六种方法
vue组件通信6种方式总结(常问知识点)1
在Vue组件库开发过程中,Vue组件之间的通信一直是一个重要的话题,虽然官方推出的 Vuex 状态管理方案可以很好的解决组件之间的通信问题,但是在组件库内部使用 Vuex 往往会比较重,本文将系统的罗列出几种不使用 Vuex,比较实用的组件间的通信方式,供大家参考。
bb_xiaxia1998
2023/01/03
5930
vue $listeners $attr_vue query
在生命周期方法mounted中打印attrs,显示除了class和props定义的属性之外的其他属性。 通过 v-bind=”attrs” 传入子组件内部的input标签
全栈程序员站长
2022/11/07
3.7K0
vue $listeners $attr_vue query
一面高频vue面试题
eventBus事件总线适用于父子组件、非父子组件等之间的通信,使用步骤如下: (1)创建事件中心管理组件之间的通信
bb_xiaxia1998
2022/10/28
8090
Vue组件数据通信方案总结
初识Vue.js,了解到组件是Vue的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:
青梅煮码
2023/01/12
1.7K0
Vue2.4中$attrs和$listeners的使用-学习笔记
在很多开发情况下,我们只是想把A组件的信息传递给C组件,如果使用props 绑定来进行信息的传递,虽然能够实现,但是代码并不美观。
全栈程序员站长
2022/11/02
9840
Vue2.4中$attrs和$listeners的使用-学习笔记
Vue 新增的$attrs与$listeners的详解
inheritAttrs:默认值true,继承所有的父组件属性(除props的特定绑定)作为普通的HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继承特性设置inheritAttrs: false,但是class属性会继承(简单的说,inheritAttrs:true 继承除props之外的所有属性;inheritAttrs:false 只继承class属性)
tianyawhl
2019/04/04
2.7K0
Vue 父子组件数据传递( inheritAttrs + $attrs + $listeners)
当我们在书写 vue 组件的时候,也许可能会用到数据传递;将父组件的数据传递给子组件,有时候也需要通过子组件去事件去触发父组件的事件;
sunseekers
2018/10/31
1.5K0
阿里前端常考vue面试题汇总_2023-02-27
使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中
用户10358241
2023/02/27
8050
vue面试经常会问的那些题
时间复杂度: 个树的完全diff 算法是一个时间复杂度为O(n*3) ,vue进行优化转化成O(n) 。
bb_xiaxia1998
2022/11/08
1K0
Vue-组件之间常用的通信方式
Vue 组件之间常用的通信方式 props 总线 eventbus vuex 自定义事件 关系情况 $parent $children $root $refs provide/inject 非 prop 特性 $attrs $listener props 父->子传值 用属性 parent <child :faData = '来自父亲'></child> child props:{ faData:{ type:String, default:""
一只眠羊
2021/03/25
6650
Vue中组件之间8种通信方式,值得收藏
vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢?首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式, 就好像过年回家,坐着一屋子的陌生人,相互之间怎么称呼,这时就需要先知道自己和他们之间是什么样的关系。vue组件中关系说明:
前端达人
2019/07/30
8800
Vue 组件数据通信方案总结
初识 Vue.js ,了解到组件是 Vue 的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:
前端迷
2019/09/25
4410
Vue 组件数据通信方案总结
腾讯二面vue面试题总结
对象内部通过 defineReactive 方法,使用 Object.defineProperty 来劫持各个属性的 setter、getter(只会劫持已经存在的属性),数组则是通过重写数组7个方法来实现。当页面使用对应属性时,每个属性都拥有自己的 dep 属性,存放他所依赖的 watcher(依赖收集),当属性变化后会通知自己对应的 watcher 去更新(派发更新)
bb_xiaxia1998
2022/11/18
7340
面试官:Vue组件间通信方式都有哪些?
都知道组件是vue最强大的功能之一,vue中每一个.vue我们都可以视之为一个组件
@超人
2021/02/26
1.4K0
面试官:Vue组件间通信方式都有哪些?
vue系列之面试总结
答:Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载 Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。 它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
桃翁
2019/05/31
1.1K0
前端常考vue面试题(必备)_2023-03-15
computed 内部实现了一个惰性的 watcher,也就是 computed watcher,computed watcher 不会立刻求值,同时持有一个 dep 实例。
yyds2026
2023/03/15
1.1K0
Vue2.x组件间通信汇总表
Dear,大家好,我是“前端小鑫同学”,😇长期从事前端开发,安卓开发,热衷技术,在编程路上越走越远~ 分享一篇以前做Vue2.x开发时总结的组件通信汇总 一、组件间通信方式表 序号 方式 使用场景 演示代码 说明 1 props 父=>子(属性传参) √ 接收数据: 子组件中props定义接收; 派发数据: 父组件中绑定数据进行派发 2 $emit/$on 子=>父组件通信(事件传参) √ 接收数据: 父组件调用$on/v-on; 派发数据: 子组件调用$emit() 3 event bus 兄弟组件通信
前端小鑫同学
2022/12/26
4340
前端一面常见vue面试题汇总_2023-02-27
eventBus事件总线适用于父子组件、非父子组件等之间的通信,使用步骤如下: (1)创建事件中心管理组件之间的通信
用户10358241
2023/02/27
7920
相关推荐
深入浅出,带你看懂Vue组件间通信的8种方案
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文