介绍
$attrs
包含了父作用域中不被props接收拿到的 (class 和 style 除外)。当一个组件没有声明任何 props 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件——在创建更高层次的组件时非常有用。
$listeners
包含了父作用域中的 (不含 .native 修饰器的) 所有v-on 事件。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用
父组件代码
<template>
<div class="">
<!-- 自定义组件使用v-model,默认会利用名为 value 的 prop 和名为 input 的事件,绑定的将在子组件中使用 value 获得,
而且给myChild组件默认会添加 @input 事件 -->
<!-- 在myChild组件里的el-input,可以通过给input添加 :value="value" v-bind="$attrs" v-on="$listeners ,
将input事件传递进去el-input,实现改变输入框能够触发父组件事件效果" -->
<myChild
v-model="value"
:maxlength="2000"
dataSon = 'dataSon'
dataSonSon = 'dataSonSon'
@mySonSonChange="mySonSonChange"
@mySonChagne="mySonChagne"/>
</div>
</template>
<script>
import myChild from './attrsAndListenersChild'
export default {
name: '',
components:{
myChild
},
data() {
return {
value:''
}
},
methods: {
mySonSonChange(){
console.log('我是父组件的myChange,但是由我子组件的子组件调用')
},
mySonChagne(){
console.log('我是父组件的myChange,但是由我子组件调用')
}
},
}
</script>
<style lang="" scoped>
</style>
父组件中,往子组件传递了 value maxlength dataSon dataSonSon 属性,mySonSonChange mySonChagne input方法 ,其中value和input来源于v-model
myChild子组件代码
// 子组件
<template>
<div class="">
<el-input :value="value" v-bind="$attrs" v-on="$listeners"></el-input>
<div>{{value.length}}/{{maxlength}}</div>
<h1>我接收了父组件的dataSon:{{dataSon}},但是没接收父组件的dataSonSon,此时attrs={{$attrs}},将传递到下一层组件</h1>
<el-button type="primary" @click="sonClick">点击触发父组件的mySonChagne</el-button>
<hr />
<!--
这个组件里接收了 value maxlength dataSon,没接收 dataSonSon,所以通过 v-bind="$attrs" 将没接收的 dataSonSon继续往下层组件传递
-->
下边的子组件的子组件{{$listeners}}
<myChildSon v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
import myChildSon from './attrsAndListenersChildSon'
export default {
name: '',
components:{
myChildSon
},
props:{
value:{
type:String
},
maxlength:{
type:Number
},
dataSon:{
type:String
}
},
data() {
return {
}
},
methods:{
sonClick(){
this.$emit('mySonChagne')
}
},
created () {
// 传入的所有v-on事件都可以在$listeners对象中找到
console.log(this.$listeners)//{mySonSonChange: ƒ, mySonChagne: ƒ, input: ƒ}
}
}
</script>
<style lang="" scoped>
</style>
在created中能够获取到 父组件的$listeners 对象,包含了所有v-on
其中 input 事件是来源于 v-model,在vue中,自定义组件使用v-model,默认会利用名为 value 的 prop 和名为 input 的事件,绑定的值将在子组件中使用 value 获得,而且给myChild组件默认会添加 @input 事件
这个组件里接收了 value maxlength dataSon,没接收 dataSonSon,所以通过 v-bind="$attrs" 将没接收的 dataSonSon继续往下层组件传递 ,点击按钮触发父组件的 mySonChagne 事件
myChildSon子子组件代码
<template>
<div class="">
<h1>这是来源于父组件的父组件的dataSonSon:{{dataSonSon}}</h1>
<el-button type="primary" @click="sonSonCilck">点我触发父组件的父组件的mySonSonChange</el-button>
</div>
</template>
<script>
export default {
name: '',
props:{
dataSonSon:{
type:String
}
},
data() {
return {
}
},
methods:{
sonSonCilck(){
this.$emit('mySonSonChange')
}
},
created () {
// 传入的所有v-on事件都可以在$listeners对象中找到
console.log(this.$listeners)//{mySonSonChange: ƒ, mySonChagne: ƒ, input: ƒ}
}
}
</script>
<style lang="" scoped>
</style>
这个组件里接收了dataSonSon,点击按钮触发父组件的 mySonSonChange 事件