组件通信-$attrs与$listeners
1.$attrs
父子组件通信的一种
$attrs与$listeners ---- 父子组件通信
$attrs:组件实例的属性,可以获取到父亲传递的props数据(前提子组件没有通过props接受)
$listeners:组件实例的属性,可以获取到父亲传递自定义事件(对象形式呈现)
看例子:
在element UI的button按钮上二次封装给他加上一个hover提示的按钮,
子组件:
<template>
  <div>
      <el-button></el-button>
  </div>
</template>
 el-button里面我们什么都没写,原因是为了引入的是一个动态的,以后我们修改按钮的内容,页面按钮样式,或者icon会动态改变
父组件:
<template>
  <div>
    <h2>自定义带Hover提示的按钮</h2>
     <HintButton/>
  </div>
</template>
<script type="text/ecmascript-6">
import HintButton from './HintButton';
export default {
  name: 'AttrsListenersTest',
  components:{ 
     HintButton 
  },
}
</script>
 目前效果:
   $attrs的使用
然后在父组件传递props数据给子组件
修改父组件:
type="success" icon="el-icon-plus"这是element的
title是自己定义的,这些都是props,
<template>
  <div>
    <h2>自定义带Hover提示的按钮</h2>
     <HintButton type="success" icon="el-icon-plus" title="我是紫陌"/>
  </div>
</template>
<script type="text/ecmascript-6">
import HintButton from './HintButton';
export default {
  name: 'AttrsListenersTest',
  components:{ 
     HintButton 
  },
}
</script>
 这回我们子组件接收父组件传递过来的参数,我们就不用props了,我们利用组件实例身上的一个属性$attrs也可以接收父组件传递给子组件的数据
注意:要是我们用props接受的话,父组件给的数据子组件通过props接收的属性,在$attrs属性当中是获取不到的
修改子组件:
<template>
  <div>
    <!-- 可以巧妙利用a标签实现按钮带有的提示功能 -->
     <a :title="title">
          <!-- 
         	这是复杂写法,也可以实现效果,但是属性多的话就很麻烦
			<el-button :type="$attrs.type" :icon="$attrs.icon" :size="$attrs.size">添加</el-button>
          -->
		<!-- 下面这种写法v-bind不能用:简写 不然没有效果,这就是简单的写法效果-->
        <el-button v-bind="$attrs">添加</el-button>
     </a>
  </div>
</template>
<script>
export default {
  name: "",
  props:['title'],
  mounted(){
    //this.$attrs:可以获取到父亲传递的数据【props】
    //this.$attrs是可以获取父亲传递的props数据,如果子组件通过
    //props:[],接受的属性,this.$attrs属性是获取不到的
    console.log(this.$attrs);
  }
};
</script>
 子组件中打印一下$attrs
   $attrs:组件实例的属性,可以获取到父亲传递的props数据(前提子组件没有通过props接受)
上面用了props接受父组件title,打印的$attrs就没有title这个属性了。不用props接受就能在$attrs获取的到。
一开始我的需求:需要封装ElementUI按钮,并且是带Hover提示的按钮,我们在el-button外面来一个a标签,因为a标签有一个title属性,就带有提示功能。现在就可以通过这个完成了。
2.$listeners地使用
这个时候我们想给按钮绑定一个点击事件,点击弹出一个999什么的,我们知道HintButton是一个组件,在组件身上写@click他就变成了自定义事件了
@click.native其实是可以解决的,但是我们这里有另外的解决办法,所以我这样来演示:
父组件:
在组件标签上绑定一个自定义事件。点击组件的时候弹出999
<template>
  <div>
    <h2>自定义带Hover提示的按钮</h2>
    <!-- 二次封装的HintButton按钮的时候,把人家el-button需要的数据传递过去 -->
     <HintButton type="success" icon="el-icon-plus" title="我是紫陌" @click="handler"/>
  </div>
</template>
<script type="text/ecmascript-6">
import HintButton from './HintButton';
export default {
  name: 'AttrsListenersTest',
  components:{
     HintButton 
  },
  methods: {
    handler() {
       alert('999');
    },
  },
}
</script>
 我们想给HintButton绑定单击事件 实际上是给el-button绑定单击事件
我们先看看$listeners身上有没有父组件传递过来的自定义事件,并且利用v-on来给el-button绑定单击事件
子组件中:
<template>
  <div>
    <!-- 可以巧妙利用a标签实现按钮带有的提示功能 -->
     <a :title="title">
          <!-- 
         	这是复杂写法,也可以实现效果,但是属性多的话就很麻烦
			<el-button :type="$attrs.type" :icon="$attrs.icon" :size="$attrs.size">添加</el-button>
          -->
		<!-- 下面这种写法v-bind不能用:简写 不然没有效果,这就是简单的写法效果-->
        <el-button v-bind="$attrs" v-on="$listeners">添加</el-button>
     </a>
  </div>
</template>
<script>
export default {
  name: "",
  props:['title'],
  mounted(){
    //this.$attrs:可以获取到父亲传递的数据【props】
    //this.$attrs是可以获取父亲传递的props数据,如果子组件通过
    //props:[],接受的属性,this.$attrs属性是获取不到的
    console.log(this.$attrs);
    // $listeners他也是组件实例自身上的一个属性,他可以获取到父组件给子组件传递的自定义事件。
    console.log(this.$listeners);
  }
};
</script>
 打印结果:
最后一个就是打印事件
   此时点击按钮就可以弹出999了
   总结:
$listeners与$attrs(组件通信方式的一种)
他们两者都是组件实例的属性,可以获取到父组件给子组件传递的props与自定义事件















![[oeasy]python0068_控制序列_清屏_控制输出位置_2J](https://img-blog.csdnimg.cn/img_convert/0a825a6550832bac039b55959c5d2d18.png)



