Vue-- $attrs与$listeners的详解
程序员文章站
2022-06-11 15:02:57
...
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
,显示除了calss
和props
定义的属性之外的其他属性。
通过 v-bind="$attrs"
传入子组件内部的input
标签
vm.$listeners
- 2.4.0新增
- 类型
{ [key: string]: Function | Array<Function> }
- 只读
- 详细
包含了父作用域中的 (不含.native
修饰器的)v-on
事件监听器。它可以通过v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用。
简单点讲它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过v-on="$listeners"
将事件监听指向这个组件内的子元素(包括内部的子组件)。
为了查看方便,我们设置inheritAttrs: true
,后面补充一下inheritAttrs
。
<div id="app">
<child1
:p-child1="child1"
:p-child2="child2"
:p-child-attrs="1231"
v-on:test1="onTest1"
v-on:test2="onTest2">
</child1>
</div>
<script>
Vue.component("Child1", {
inheritAttrs: true,
props: ["pChild1"],
template: `
<div class="child-1">
<p>in child1:</p>
<p>props: {{pChild1}}</p>
<p>$attrs: {{this.$attrs}}</p>
<hr>
<child2 v-bind="$attrs" v-on="$listeners"></child2></div>`,
mounted: function() {
this.$emit("test1");
}
});
Vue.component("Child2", {
inheritAttrs: true,
props: ["pChild2"],
template: `
<div class="child-2">
<p>in child->child2:</p>
<p>props: {{pChild2}}</p>
<p>$attrs: {{this.$attrs}}</p>
<button @click="$emit('test2','按钮点击')">触发事件</button>
<hr> </div>`,
mounted: function() {
this.$emit("test2");
}
});
const app = new Vue({
el: "#app",
data: {
child1: "pChild1的值",
child2: "pChild2的值"
},
methods: {
onTest1() {
console.log("test1 running...");
},
onTest2(value) {
console.log("test2 running..." + value);
}
}
});
</script>
上例中,父组件在child1
组件中设置两个监听事件test1
和test2
,分别在child1
组件和child1
组件内部的child2
组件中执行。还设置了三个属性p-child1
、p-child2
、p-child-attrs
。其中p-child1
、p-child2
被对应的组件的prop
识别。所以:p-child1
组件中$attrs
为{ "p-child2": "pChild2的值", "p-child-attrs": 1231 }
;p-child2
组件中$attrs
为{ "p-child-attrs": 1231 }
。
效果如下图:
我们再点击child2
组件中的按钮,触发事件,控制台可以打印出:
补充
inheritAttrs
- 2.4.0新增
- 类型
boolean
- 默认值:
true
- 详细
默认情况下父作用域的不被认作props
的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置inheritAttrs
到false
,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性$attrs
可以让这些特性生效,且可以通过v-bind
显性的绑定到非根元素上。
注意:这个选项不影响 class 和 style 绑定。
上例中同样的代码,设置了inheritAttrs: true
,元素结构显示如下图:
没有被props
绑定的属性placeholder
和test-attrs
显示到了子组件根节点上了。
下面我们把上例中设置inheritAttrs: false
,元素结构显示如下图:
没有被props
绑定的属性就没有作为普通的 HTML 特性应用在子组件的根元素上。
下一篇: Shiro - 简单配置