Vue-- $attrs与$listeners的详解
1、vm.$attrs2.4.0新增类型 { [key: string]: string }只读详细包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
1、vm.$attrs
- 2.4.0新增
- 类型 { [key: string]: string }
- 只读
- 详细
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
简单点讲就是包含了所有父组件在子组件上设置的属性(除了prop传递的属性、class 和 style )。
<div id="app">
<base-input
label="姓名"
class="name-input"
placeholder="请输入姓名"
test-attrs="$attrs"
></base-input>
</div>
Vue.component("base-input", {
inheritAttrs: true, //此处设置禁用继承特性
props: ["label"],
template: `
<label>
{{label}}-
{{$attrs.placeholder}}-
<input v-bind="$attrs"/>
</label>
`,
mounted: function() {
console.log(this.$attrs);
}
});
const app = new Vue({
el: "#app"
});
在生命周期方法mounted中打印$attrs,显示除了class和props定义的属性之外的其他属性。
通过 v-bind="$attrs" 传入子组件内部的input标签
2、 vm.$listeners
- 2.4.0新增
- 类型 { [key: string]: Function | Array }
- 只读
- 详细
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
简单点讲它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on="$listeners" 将事件监听指向这个组件内的子元素(包括内部的子组件)。
为了查看方便,我们设置inheritAttrs: true,后面补充一下inheritAttrs。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>arrs与listeners</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child1 :a-child1="aChild1" :a-child2="aChild2" name1="组件1" name2="组件2" attrs='attrs' @test1="test1" @test2="test2"></child1>
</div>
<!-- 主要是理解$attrs与$listeners这两个属性-->
<script>
Vue.component('child1',{
inheritAttrs: true,
props:['a-child1'],
mounted(){
console.log(this.$attrs);
console.log(this.$listeners);
},
methods:{
test1(){
this.$emit('test1')
}
},
template:`<div>{{$attrs.name1}}:{{aChild1}}</br> attrs:{{this.$attrs}}</br><button @click="test1">test1</button><child2 v-on="$listeners" v-bind='$attrs'></child2></div>`
});
Vue.component('child2',{
inheritAttrs: true,
props:['a-child2'],
mounted(){
console.log(this.$attrs);
console.log(this.$listeners);
},
template:`<div>{{$attrs.name2}}:{{aChild2}}</br> attrs:{{this.$attrs}}</br> <button @click='$listeners.test2'>test2</button></div>`
});
var app = new Vue({
el:"#app",
data:{
aChild1:'加油',
aChild2:'努力',
},
methods:{
test1(){
console.log('child1---')
},
test2(){
console.log('child2---')
}
}
});
</script>
</body>
</html>
上例中,父组件在child1组件中设置两个监听事件test1和test2,分别在child1组件和child1组件内部的child2组件中执行。还设置了三个属性aChild1、aChild2、name1、name2、attrs。其中aChild1、aChild2被对应的组件的prop识别。所以:
child1组件中$attrs为{ “a-child2”: “努力”, “name1”: “组件1”, “name2”: “组件2”, “attrs”: “attrs” };
child2组件中$attrs为{ “name1”: “组件1”, “name2”: “组件2”, “attrs”: “attrs” }
效果如下图:
child2组件中的$attrs和$listeners打印的内容
3、inheritAttrs
- 2.4.0新增
- 类型 boolean
- 默认值:true
- 详细
默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML
特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrs 到false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过v-bind 显性的绑定到非根元素上。inheritAttrs设置为false,不影响$attrs,子组件通过$attrs依然可以获取到父组件传过来的属性值。
注意:这个选项不影响 class 和 style 绑定。
vm.$listeners的案例如果 inheritAttrs设置为false,html显示如下:
如果inheritAttrs设置为true,html显示如下:
更多推荐
所有评论(0)