一个非 prop 特性(属性)是指传向一个组件,但是该组件并没有相应 prop 定义的特性。
Vue.component('test-prop', {
// 在组件props中只定义了param1
props: ['param1'],
inheritAttrs: false, // 详情见 ↓ 附录1
template: '<div></div>',
mounted() {
console.log(this.param1); // 值1
console.log(this.param2); // undefined
console.log(this.$attrs); // 返回父作用域中非 prop 的特性 (class 和 style 除外)的对象集合
console.log(this.$attrs.param1); // undefined
console.log(this.$attrs.param2); // 值2
console.log(this.$listeners); // 返回父作用域中的 (不含 .native 修饰器的) v-on 事件集合
console.log(this.$listeners.event1); // fn1
console.log(this.$listeners.event2); // undefined
this.$emit('event1');
}
})
<test-prop
param1="值1"
param2="值2"
v-on:event1="fn1"
v-on:event2.native="fn2"></test-prop>
<!-- 此时 传入的param2 即为 非 prop 的特性 -->
通过 $attrs
及 $listeners
属性可以降低在不使用Vuex以及事件总线的情况下,组件跨级props以及事件传递的复杂度。
<!-- 组件A -->
<template>
<div id="app">
<B :propB="值" type="password" @test1="onTest1" @test2="onTest2"></B>
</div>
</template>
<script>
export default {
components: { B },
methods: {
onTest1() { console.log('我是A组件的方法Test1'); },
onTest2() { console.log('我是A组件的方法Test2'); }
}
};
</script>
<!-- 组件B -->
<template>
<div>
<!-- 中间件,将type传入C组件,将事件onTest1、onTest2传递 -->
<C v-bind="$attrs" v-on="$listeners"></C>
</div>
</template>
<script>
export default {
props: ['propB'],
inheritAttrs: false,
components: { C },
mounted() {
this.$emit('test1'); // 执行 test1
}
};
</script>
<!-- 组件C -->
<template>
<!-- 此时若设置 inheritAttrs 为 true,会导致该input框的type值为password -->
<input type="text">
</template>
<script>
export default {
props: ['child2'],
inheritAttrs: false,
mounted() {
this.$emit('test2'); // 执行 test2
}
};
</script>
附录1:
inheritAttrs
默认情况下父作用域的非 prop 的特性会 挂载到 根元素(属性)上,通过设置 inheritAttrs
到 false
可去除。
注意:这个选项不影响 class
和 style
绑定。
<div param2="值2"></div>
将 `inheritAttrs` 设为 `false` 后
<div></div>
摘录于:Vue官网