$attrs和$listeners的使用-學(xué)習(xí)筆記

介紹

$attrs

包含了父作用域中不被props接收拿到的 (class 和 style 除外)。當(dāng)一個(gè)組件沒有聲明任何 props 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外),并且可以通過 v-bind=”$attrs” 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用。

$listeners

包含了父作用域中的 (不含 .native 修飾器的) 所有v-on 事件。它可以通過 v-on=”$listeners” 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用

父組件代碼

<template>
  <div class="">
    <!-- 自定義組件使用v-model,默認(rèn)會(huì)利用名為 value 的 prop 和名為 input 的事件,綁定的將在子組件中使用 value 獲得,
而且給myChild組件默認(rèn)會(huì)添加 @input 事件 -->
    <!-- 在myChild組件里的el-input,可以通過給input添加 :value="value" v-bind="$attrs" v-on="$listeners ,
將input事件傳遞進(jìn)去el-input,實(shí)現(xiàn)改變輸入框能夠觸發(fā)父組件事件效果" -->
    <myChild 
        v-model="value" 
        :maxlength="2000" 
        dataSon = 'dataSon' 
        dataSonSon = 'dataSonSon' 
        @mySonSonChange="mySonSonChange" 
        @mySonChagne="mySonChagne"/>
  </div>
</template>

<script>
import myChild from './attrsAndListenersChild'
export default {
  name: '',
  components:{
    myChild
  },
  data() {
    return {
      value:''
    }
  },
  methods: {
    mySonSonChange(){
      console.log('我是父組件的myChange,但是由我子組件的子組件調(diào)用')
    },
    mySonChagne(){
      console.log('我是父組件的myChange,但是由我子組件調(diào)用')
    }
  },
 }
</script>

<style lang="" scoped>
</style>

父組件中,往子組件傳遞了 value maxlength dataSon dataSonSon 屬性,mySonSonChange mySonChagne input方法 ,其中value和input來源于v-model

myChild子組件代碼

// 子組件
<template>
  <div class="">
    <el-input :value="value" v-bind="$attrs" v-on="$listeners"></el-input>
    <div>{{value.length}}/{{maxlength}}</div>


    <h1>我接收了父組件的dataSon:{{dataSon}},但是沒接收父組件的dataSonSon,此時(shí)attrs={{$attrs}},將傳遞到下一層組件</h1>
    <el-button type="primary" @click="sonClick">點(diǎn)擊觸發(fā)父組件的mySonChagne</el-button>






    <hr />
    <!--
      這個(gè)組件里接收了 value maxlength dataSon,沒接收 dataSonSon,所以通過 v-bind="$attrs" 將沒接收的 dataSonSon繼續(xù)往下層組件傳遞
    -->
    下邊的子組件的子組件{{$listeners}}
    <myChildSon v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>

<script>
import myChildSon from './attrsAndListenersChildSon'
export default {
  name: '',
  components:{
    myChildSon
  },
  props:{
    value:{
      type:String
    },
    maxlength:{
      type:Number
    },
    dataSon:{
      type:String
    }
  },
  data() {
    return {

    }
  },
  methods:{
    sonClick(){
      this.$emit('mySonChagne')
    }
  },
  created () {
    // 傳入的所有v-on事件都可以在$listeners對(duì)象中找到
    console.log(this.$listeners)//{mySonSonChange: ?, mySonChagne: ?, input: ?}
  }
 }
</script>

<style lang="" scoped>
</style>

在created中能夠獲取到 父組件的$listeners 對(duì)象,包含了所有v-on

image.png

其中 input 事件是來源于 v-model,在vue中,自定義組件使用v-model,默認(rèn)會(huì)利用名為 value 的 prop 和名為 input 的事件,綁定的值將在子組件中使用 value 獲得,而且給myChild組件默認(rèn)會(huì)添加 @input 事件

這個(gè)組件里接收了 value maxlength dataSon,沒接收 dataSonSon,所以通過 v-bind="$attrs" 將沒接收的 dataSonSon繼續(xù)往下層組件傳遞 ,點(diǎn)擊按鈕觸發(fā)父組件的 mySonChagne 事件

image.png

myChildSon子子組件代碼

<template>
  <div class="">
    <h1>這是來源于父組件的父組件的dataSonSon:{{dataSonSon}}</h1>
    <el-button type="primary" @click="sonSonCilck">點(diǎn)我觸發(fā)父組件的父組件的mySonSonChange</el-button>
  </div>
</template>

<script>
export default {
  name: '',
  props:{
    dataSonSon:{
      type:String
    }
  },
  data() {
    return {

    }
  },
  methods:{
    sonSonCilck(){
      this.$emit('mySonSonChange')
    }
  },
  created () {
    // 傳入的所有v-on事件都可以在$listeners對(duì)象中找到
    console.log(this.$listeners)//{mySonSonChange: ?, mySonChagne: ?, input: ?}
  }
 }
</script>

<style lang="" scoped>
</style>

這個(gè)組件里接收了dataSonSon,點(diǎn)擊按鈕觸發(fā)父組件的 mySonSonChange 事件

image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容