vue中使用v-bind=“$attrs“和v-on=“$listeners“进行多层组件监听

  • Post author:
  • Post category:vue




vue中使用v-bind=”



a

t

t

r

s

v

o

n

=

attrs”和v-on=”






a


t


t


r


s








v













o


n




=














listeners”进行多层组件监听

vue组件之间通信,我们可以使用props和vuex两种方式,但是vuex太重,props在多级组件中使用又太麻烦,vue2.4版本提供了另一种方法,使用v-bind=”$attrs”,将父组件中不被认为 props特性绑定的属性传入子组件中,通常配合 interitAttrs 选项一起使用。

例如下面的层级关系

<top>
  <center>
    <bottom>
    </bottom>
  </center>
</parent>

如果top组件要和bottom组件进行通信,下面有三种方式可以实现

1.通过props和$emit的方式,需要通过center作为中转,top把值传给center,center再把值传给bottom,或者bottom把值传给center,center在传给top

2.使用vuex,但是这两个组件的状态可能不是全局状态

3.使用中央事件总线bus

使用前两种方式可能都不太理想,这里来讲一下另一种方式

先看一下代码片段

top组件,传递了name,age,gender,sdf四个属性到子组件center,然后接收了两个isClick()和asd()方法

<template>
  <section>
    <centers
      name="name"
      age="18"
      gender="666"
      sdf="asd"
      @isClick="isClick"
      @asd="asd"
    ></centers>
  </section>
</template>
<script>
  import centers from '~/components/center';
  export default {
    components: {
      centers
    },
    methods: {
      asd() {
        console.log(999);
      },
      isClick() {
        console.log(666);
      }
    }
  };
</script>

center组件,只接收了name和age两个属性,其他属性没有接收,使用 v-bind=”



a

t

t

r

s

v

m

.

attrs” 属性,`vm.






a


t


t


r


s

















v


m


.





attrs

是一个属性,其包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。这些未识别的属性可以通过

v-bind=“



a

t

t

r

s

v

o

n

=

attrs”` 传入内部组件。未识别的事件可通过`v-on=”






a


t


t


r


s



























































v













o


n




=














listeners”`传入(.native绑原生事件是没用的)。

<template>
  <section>
    <div class="mt-10">
      <bottom v-bind="$attrs" v-on="$listeners" />
    </div>
  </section>
</template>

<script>
  import bottom from '~/components/bottom';
  export default {
    components: {
      bottom
    },
    props: {
      name: {
        type: String,
        default: 'default'
      },
      age: {
        type: String,
        default: 'default'
      }
    }
  };
</script>

bottom组件,我们只接收了gender属性,但是这个属性是其父组件center使用 v-bind=”$attrs” 从top组件接收到的,center组件本身并没有使用props接收这个属性,但是bottom属性确可是使用

<template>
  <section>
    <div>
      {{ $attrs['gender'] }}  在$attrs里面只会有props没有注册的属性
      <br>
      {{ gender }}
    </div>
  </section>
</template>

<script>
  export default {
    props: {
      gender: {
        type: String,
        default: ''
      }
    },
    mounted() {
      console.log(this.$attrs);
      console.log(this.$listeners);
      this.$listeners.isClick();
      this.$listeners.asd();
    }
  };
</script>

总结

1.v-bind=”$props”: 可以将父组件的所有props下发给它的子组件,子组件需要在其props:{} 中定义要接受的props。

vm.$props: 当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。

2.v-bind=”$attrs”: 将调用组件时的组件标签上绑定的非props的特性(class和style除外)向下传递。在子组件中应当添加inheritAttrs: false(避免父作用域的不被认作props的特性绑定应用在子组件的根元素上)。


vm.$attrs

:包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件——在创建高级别的组件时非常有用。

3.v-on=”将父组件标签上的自定义事件向下传递其子组件可以直接通过emit(eventName)的方式调用。


vm.$listeners

: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。

4.举例说明:

4.1.如上实例代码中,top组件传值给center可以全部不接收,然后直接通过 v-bind=”$attrs” 传给bottom,然后bottom组件直接使用props接收top传过来的所有属性

4.2.在别人组件的基础上进行二次封装的时候,定义好自己的属性,然后在自己的组件上直接传值,然后通过 v-bind=”$attrs” 把值传给别人的组件即可,例如

<template>
  <div>
    <el-button v-bind="$attrs">确定</el-button>
  <div>
</template>
 
// 父组件使用
<my-button type='primary' size='mini'/>

5.vm.



a

t

t

r

s

v

m

.

attrs和vm.






a


t


t


r


s





v


m


.





listeners获取到的值都是json的形式,对应每一个属性和取值



版权声明:本文为qq_43770034原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。