vue $attrs和$listenners

发布时间:2024年01月19日

Vue2.x 中的a t t r s 和 attrs和attrs和listeners
或许很多Vue小白跟我一样, 在之前不太了解a t t r s 和 attrs和attrs和listenners这两个API是干嘛的, 甚至没有听过或者使用过。下面我来浅述一下我对这两个API的理解。

下文将基于下面这张图片来进行解释,现在我们有三个组件, 组件之间的结构关系如下图所示: A:爷爷组件、B:父亲组件、C:儿子组件

$attrs

为什么要用$attrs?

场景: 现在组件的结构如上图所示,我们要实现由A组件到C组件之间的数据通信,有几种实现方式?

像我一样的小白或许刚好学了Props,此时一股脑将所有的属性写在B组件的Props中,这个方案固然可行,但是如果C组件下面还有组件呢?C的子孙千千万,B的Props中的属性也将变成千千万。不得不说B作为父亲的压力是真的大,不仅仅要养活C,还要养活C将来可能存在的千万子孙。这种解决方案无疑给后续的代码维护造成了比较大的阻碍。
或许学完了Props的小伙伴们又说了,那我们是不是可以借助其它工具?例如VueX这样的工具来实现,没错!VueX当然也可以实现以上场景,但是如果C中会用到的属性值很少,那么此时使用VueX来介入这样的问题,是否有点 ‘大动干戈’ 了呢?

能够解决(父→子)通信这类问题的手段有很多,正所谓没有最好的解决方案, 只有更适合的解决方案。在本文中主要踢一下$attrs这个API的使用。

怎么使用$attrs?
在vue2.4中,为了更好的解决上面这类场景的问题,引入了$attrs这一API来帮助咱开发者来解决这个问题。话不多说上代码:

?

<!-- 爷爷组件A -->
<template>
  <div>
    <my-father :foo="foo"
      :bar="bar"
      :fatherName="'老王'"
      :sonName="'小王'">
    </my-father>
  </div>
</template>
<script>
import MyFather from "./MyFather.vue";
export default {
  components: {
    MyFather,
  },
  data () {
    return {
      foo: "foo",
      bar: "bar",
    };
  },
};
</script>
<!-- 父亲组件B -->
<template>
  <div>
    <p>----------------------------</p>
    <p>father中的foo:{{ foo }}</p>
    <p>father中的attrs: {{ $attrs }}</p>
    <my-son v-bind="$attrs"></my-son>
  </div>
</template>
<script>
import MySon from "./MySon.vue";
export default {
  props: ["foo", "fatherName"],
  components: {
    MySon,
  },
  created () {
    console.log('father组件中的$attrs:', this.$attrs);
  }
};
</script>
<!-- 孙子组件C -->
<template>
  <div>
    <p>----------------------------</p>
    <p>son中的bar:{{ bar }}</p>
    <p>son中的$attrs:{{ $attrs }}</p>
  </div>
</template>
<script>
export default {
  props: ["bar"],
  created () {
    console.log('son组件中的$attrs:', this.$attrs);
  }
};
</script>

页面显示如下:

从上面程序运行的结果, 相信能够看到$attrs的威力了, 它能够让咱们在解决父子通信、爷孙通信这类问题场景的时候更加优雅。毕竟优雅永不过时嘛

$listeners
爷爷 → 孙子 讲完了, 接下来看看咱们如何优雅地解决 爷爷 ← 孙子 的问题。

为什么要用$listenners?
场景: 现在组件之间的结构如最上面的图所示,我们要实现由C组件到A组件之间的数据通信,有几种实现方式?

可以在C组件中使用$emit()方法, 抛出一个事件给B组件, B组件再调用$emit()方法抛给A组件, 像这样一层一层往上传递。在组件关系、组件功能都不复杂的情况下,使用这种方法可以快速完成子组件到父组件之间的通信。
通过VueX来实现父子组件通信
父组件通过ref来调用子组件的方法
?

?

能够解决(父←子)通信这类问题的手段有很多,正所谓没有最好的解决方案, 只有更适合的解决方案。接下来主要踢一下$listenners这个API的使用。

怎么使用$listenners?

话不多说, 上代码:

<!-- 爷爷组件A -->
<template>
  <div>
    <my-father :foo="foo" @updateFoo="update" />
  </div>
</template>
<script>
import MyFather from "./MyFather.vue";
export default {
  components: {
    MyFather,
  },
  data () {
    return {
      foo: "foo",
    };
  },
  methods: {
    update (newValue) {
      this.foo = newValue
      console.log("update success");
    }
  }
};
</script>
<!-- 父亲组件B -->
<template>
  <div>
    <p>father中的foo:{{ foo }}</p>
    <my-son v-bind="$attrs" v-on="$listeners" />
  </div>
</template>
<script>
import MySon from "./MySon.vue";
export default {
  props: ["foo"],
  inheritAttrs: false,
  components: {
    MySon,
  },
};
</script>
<!-- 孙子组件C -->
<template>
  <div>
    <button @click="sonFun">更新foo</button>
  </div>
</template>
<script>
export default {
  props: ["bar"],
  methods: {
    sonFun () {
      this.$emit("updateFoo", "oof");
      console.log("sonFun!!!");
    }
  }
};
</script>

通过观察我们发现, 由C组件到A组件之间的通信仅用到了一次e m i t ( ) , 这一小小的举动让我们的组件通信变得更加优雅了 , 我们只需要在 B 组件使用 C 组件的地方加上一句 ‘ v ? o n = " emit(), 这一小小的举动让我们的组件通信变得更加优雅了, 我们只需要在B组件使用C组件的地方加上一句`v-on="emit(),这一小小的举动让我们的组件通信变得更加优雅了,我们只需要在B组件使用C组件的地方加上一句‘v?on="listeners"`就可以让A组件监听到C组件抛出的事件。看完本文后是否对$attrs 和 $listenners 有了深刻的认识呢?

文章来源:https://blog.csdn.net/weixin_44692055/article/details/135691897
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。