组件事件属性穿透
属性
$attrs
包含从父组件传过来的属性,但不包含子组件中prop中的属性以及class
和style
,因此对于那些html元素原生属性,能够不用再子组件中声明,直接从父组件中传进来就好
// 子组件
<template>
<div>
<input type="text" name="" id="" v-bind="$attrs" v-on='listeners'/>
</div>
</template>
props: {
test: {
type: String,
default: '123456'
}
},
created () {
console.log(`props:%o`, this.$props) // {test: '测试'}
console.log('attrs:%o', this.$attrs) // {value: '测试'}
},
// 父组件
<myInput :value="value" :class="class_" :style='style' :test='test' @input1="input"/>
data () {
return {
style: {
color: 'red'
},
value: '测试',
class_: 'test',
test: '测试'
}
}
- 因为在这个组件中input并非根元素,默认状况下父组件的不被认做 props 的特性绑定将会“回退”且做为普通的 HTML 特性应用在子组件的根元素上,在该例子中根节点div会有
value="测试"
的属性,因此子组件须要设置 inheritAttrs: false去掉根元素默认行为,这样就能够经过实例属性 $attrs
能够让这些特性生效,且能够经过 v-bind 显性的绑定到非根元素上。
- 在子组件修改props,却不会修改父组件,这是由于extractPropsFromVNodeData中是经过浅复制将父组件中数据传递给props的。 浅复制意味着在子组件中对对象和数组的props进行修改仍是会影响父组件,这就违背了单向数据流的设计。所以须要避免这种状况出现。
事件
$listeners
包含了父做用域中的 (不含 .native
修饰器的) v-on
事件监听器。它能够经过 v-on="$listeners"
传入内部组件
computed: {
listeners () {
return {
...this.$listeners,
// 下面写须要从子组件事件传值到从父组件中的
input: e => {
this.$emit('input1', e.target.value)
}
}
}
},