vue組件事件屬性穿透

組件事件屬性穿透

屬性

  • $attrs包含從父組件傳過來的屬性,但不包含子組件中prop中的屬性以及classstyle,因此對於那些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: '測試'
    }
  }
  • 注意:
  1. 因爲在這個組件中input並非根元素,默認狀況下父組件的不被認做 props 的特性綁定將會「回退」且做爲普通的 HTML 特性應用在子組件的根元素上,在該例子中根節點div會有value="測試"的屬性,因此子組件須要設置 inheritAttrs: false去掉根元素默認行爲,這樣就能夠經過實例屬性 $attrs 能夠讓這些特性生效,且能夠經過 v-bind 顯性的綁定到非根元素上。
  2. 在子組件修改props,卻不會修改父組件,這是由於extractPropsFromVNodeData中是經過淺複製將父組件中數據傳遞給props的。 淺複製意味着在子組件中對對象和數組的props進行修改仍是會影響父組件,這就違背了單向數據流的設計。所以須要避免這種狀況出現。

事件

  • $listeners包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它能夠經過 v-on="$listeners" 傳入內部組件
computed: {
    listeners () {
      return {
        ...this.$listeners,
        // 下面寫須要從子組件事件傳值到從父組件中的
        input: e => {
          this.$emit('input1', e.target.value)
        }
      }
    }
  },
相關文章
相關標籤/搜索