Vue 中 $attrs 与 $listeners

我们知道,向子组件传递数据,是通过 v-bind 子类组件定义的 props 属性完成的,这只适用于单向、两层组件之间。同样地,事件传递也是在父组件中用 v-on 给子组件绑定事件,然后在子组件中通过 this.$emit 触发的、以达到修改父组件数据的目的。

那么,在多层嵌套组件中,顶层组件和最底层组件之间如何进行数据传递和事件触发呢?比如,A 组件引用了 B 组件,而 B 组件又引用了 C 组件,那么怎么在 A 中将数据传给 C ;在 C 中,怎么触发 A 中的方法呢?这就是 $attrs$listeners 的作用了。

1.$attrs

继承所有的父组件属性(没有通过 props 接收的属性还有 class 类名 和 style 样式 )。

javascript 复制代码
// parent.vue
<m-child :data-status="dataStatus" :data-message="dataMessage"></m-child>

export default {
	data(){
		return {
			dataStatus: '123',
			dataMessage: '456'
		}
	}
}
// m-child.vue
<m-grandron v-bind="$attrs" data-message="789"></m-grandron>
export default {
	props:{
		dataStatus: String,
	},
	created(){
		console.log('dataStatus',this.dataStatus)  //  123
		console.log('dataMessage',this.dataStatus)  //  456
	}
}
// m-grandron.vue
export default {
	created(){
		console.log('dataStatus',this.$attrs)  
// 因为child组件中props声名了dataStatus所以这里$attrs就不含有dataStatus
// 因为传的dataMessage和$attrs内同名,所以值被覆盖变为789 
	}
}

如果我们按常规的props传值,就要一层一层传,层级多了就很恶心,使用$attrs就很轻松的做到了。

2.$listeners

它是一个对象,能接收所有的方法绑定,里面包含了作用在这个组件上的所有监听器,配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。

有一点不同的是:当出现同名的事件时,不会被覆盖,而是都会执行,执行顺序就是事件冒泡的执行顺序,先触发child 再触发parent\

typescript 复制代码
// parent.vue
<m-child @customEvent="ev_customEvent"></m-child>

export default {
	data(){
		return {
			dataStatus: '123',
			dataMessage: '456'
		}
	},
	methods:{
		ev_customEvent(){
			console.log('my name is parent!')
		}
	}
}
// m-child.vue
<m-grandron v-on="$listeners" @customEvent="ev_customEvent"></m-grandron>
export default {
	props:{
		dataStatus: String,
	},
	data(){
		return {}
	},
	methods:{
		ev_customEvent(){
			console.log('my name is child!')
		}
	}
}
// m-grandron.vue
<button @click="$emit('customEvent')">click me!</button>
export default {
	data(){
		return {}
	},
}


// 控制台
// my name is child!
// my name is parent!

使用$listeners 属性可以很方便的在层级很深的组件内,立马就修改最外层的父组件内的属性值

注意:在vue3.0 中$listeners被移除了,将所有属性都集合到attrs里面了

相关推荐
满分观察网友z2 分钟前
别小看这个滑动条!从性能灾难到用户挚爱的 uni-app Slider 踩坑实录
前端
编程猪猪侠3 分钟前
Taro+Vue3实现微信小程序富文本编辑器组件开发指南
vue.js·微信小程序·taro
满分观察网友z5 分钟前
别再裸写<textarea>了!一个“小”功能,我用上了它几乎所有API
前端
西西木科技丨Shopify开发机构11 分钟前
如何在 Shopify 中建立重定向
前端·html
汪子熙17 分钟前
深入探析 header facets:定位与应用
前端·javascript
你听得到1118 分钟前
从需求到封装:手把手带你打造一个高复用、可定制的Flutter日期选择器
前端·flutter
江城开朗的豌豆22 分钟前
Vue Router vs location.href:导航跳转的正确姿势,你选对了吗?
前端·javascript·vue.js
小磊哥er27 分钟前
【前端工程化】如何制定前端项目中的页面模版?
前端
Liudef0630 分钟前
基于HTML与Java的简易在线会议系统实现
java·前端·html
2401_8812444033 分钟前
javaweb———html
前端·javascript·html