Vue: $listeners和$attrs

发布于 2024-07-26  1834 次阅读


A组件

<template>
  <div>
     <B :a="a" :b="b" @changeData="changeData" @another="another"></B>
  </div>
</template>

<script>
  import B from './B.vue'
  export default {
    name: 'A',
    components: {
      B
    },
    data () {
      return {
        a: 'a',
        b: 'b'
      }
    },
    methods: {
      changeData (params) {
         this.a = params
      },
      another () {
        alert(2)
      }
    }
  }
</script>


B组件

<template>
  <div>
     <C v-bind="$attrs" v-on="$listeners" ></C>
  </div>
</template>

<script>
  import C from './C.vue'
  export default {
    name: 'B',
    components: {
      C
    },
    props: {
     a: String
    },
    data () {
      return {
      }
    },
    created () {
       console.log('this.$attrs', this.$attrs) 
       // b: b   this.$attrs 只会输出不在props中传递的属性
    },
    methods: {
    }
  }
</script>

对于子组件 要想真正实现多组件间相互传递 一般要在组件上加上inheritAttrs: false。 inheritAttrs: false可理解为:子组件props中并没有接受b设置选项 inheritAttrs: false,同样也不会作为根元素的属性节点。 没有被接收的数据都被 $attrs 实例属性给接收,里面包含着所有父组件传递给子组件并没有在 Props里显示接收的数据

v-bind="$attrs" 可以继续向下传输。 只会输出不在props中传递的属性

C组件

<template>
  <div>
    <button @click='$listeners.changeData("gg")'>改变数组</button>
    <button @click='handleOther'>其他</button>
  </div>
</template>

<script>
  export default {
    name: 'C',
    data () {
      return {
      }
    },
    created () {
       console.log('this.$attrs', this.$attrs)
       // a: a,
       // b: b
    },
    methods: {
      handleOther () {
         this.$listeners.another()
      }
    }
  }
</script>

B组件没有对A组件的事件做任何处理而是通过v-on="$listeners"向下传给给了C组件

v-on="$listeners 可在html上直接触发, 也可在js中调用触发

将原生事件绑定到组件

你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on 的 .native 修饰符:

<base-input v-on:focus.native="onFocus"></base-input>

欢迎欢迎~热烈欢迎~