介绍:vue
组件之间的通信方式有很多种,props/emit , event bus, vuex, provide/inject
等,还有一种通信方式就是 $attrs
和 $listeners
,下面通过一个三代组件的关系来看一下这两个属性
$attrs
包含了父作用域中不作为prop
识别的特性绑定(除了class
和 style
),如果没有声明prop
,就会包含父作用域所有的绑定,传入内部组件
简而言之就是 接收除了props声明外的所有绑定属性(class , style 除外)
//一级 ------------------------------------------------------------------------------------------------------------
<div class="details">
<h1>父组件---{{msg}}</h1>
<myComponent :name="msg" age="12" gender="man" ></myComponent>
</div>
//二级 ------------------------------------------------------------------------------------------------------------
<-- <div :name="msg" age="12" gender="man" class="child"> -->
<div class="child">
<h2>子组件----{{$attrs.name}}</h2>
<Son v-bind="$attrs"/>
</div>
created () {
window.console.log(this.$attrs); //{name: "小白", age: "12", gender: "man"}
} ,
//如果组件内部显示的声明了props , 那么$attrs 中就只包含除了声明的props之外的属性{age: "12", gender: "man"}
//props: ["name"],
//三级 ------------------------------------------------------------------------------------------------------------
<div class="son">
<h3>孙组件---{{$attrs.age}}</h3>
</div>
created () {
window.console.log(this.$attrs); //{name: "小白", age: "12", gender: "man"}
} ,
$listeners
官网解释 : 包含了父作用域中v-on
事件监听器(不包含 .native
修饰器的),可以通过v-on=$listeners 传入内部组件,在创建更高层次的组件时很有用
个人理解 :父作用域中的事件(除了 .native
之外)可以传入到内部组件(可以是一级 , 二级 ,,,多级),使内部组件的数据传递到父级组件更加方便
//一级 ------------------------------------------------------------------------------------------------------------
<div class="details">
<h1>父组件---{{msg}}</h1>
<myComponent @name="getname" @age="getage" @gender="getgender" ></myComponent>
</div>
methods: {
getname(e){
window.console.log("name",e) // name 小编
},
getage(){
window.console.log("age")
},
getgender(){
window.console.log("gender")
}
//二级 ------------------------------------------------------------------------------------------------------------
<div class="child">
<Son v-on="$listeners"/>
</div>
created () {
window.console.log(this.$listeners) // {name: ƒ, age: ƒ, gender: ƒ}
} ,
//三级 ------------------------------------------------------------------------------------------------------------
<div class="son">
<h3 v-on="$listeners"></h3>
<button @click="toname">点击</button>
</div>
data() {
return {
name: "小编"
};
},
created() {
window.console.log(this.$listeners);
},
methods: {
toname() {
this.$listeners.name(this.name);
}
}
案例
将element ui 的分页器封装成一个组件,使用的$attrs
和 $listeners
是原本是第三方组件的属性和事件可以在自己封装的组件中使用,(可以参考官网的element ui 分页器对比属性和事件的写法)
//组件
<Pagenation
v-if="list && list.length > 0"
class="pagenation"
:total="total"
:page-size="pagesize"
@current-change="onPageChange"
:current-page.sync="currentPage"
/>
//element 组件
<el-pagination
layout="prev, pager, next"
v-bind="$attrs"
v-on="$listeners">
</el-pagination>
网友评论