組件事件屬性穿透
屬性
$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)
}
}
}
},