vue $attrs和$listeners的使用与区别

 更新时间:2022年02月10日 09:40:32   作者:wangqinquan  
本文主要介绍了vue $attrs和$listeners的使用与区别,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

首先让我们看一下这张图,表示了一个多级关联的组件嵌套

为什么要用$attrs$listeners

先让我们来想一种情况,就是组件A跟组件C怎么通信,我们可以有多少中解决方案?

  • 看到这种情况,大多数人应该会想到用vuex来进行数据通信吧,但是如果项目中多个组件中的共享状态很少,且项目比较小,全局数据通信也很少,那我们用vuex来实现这个功能,就感觉有点杀鸡用牛刀了
  • 我们可以使用组件B来做通信的中转站,当组件A需要把数据传到组件C时,组件A通过props将数据传给组件B,然后组件B再用props传给组件C,这是一种解决方案,但是如果嵌套的组件过多,就会导致代码冗余且繁琐,维护就比较困难,而且如果组件C也要将数据传给组件A,也要一层一层往上传递,就更麻烦了
  • 自定义一个Vue数据总线,这种适合组件跨级传递数据,但是缺点是碰到多人合作时,会导致代码的维护性较低,代码可读性也较低
  • 还有一种解决方案,就是用provide inject,但是这种方式,官方不推荐,因为这个方法真的是太不好管控了,比如说我在根组件provide了this,孙孙重孙组件去使用了this里面的一个变量,这时候很难去跟踪到这个变量的出处了,而且你也并不知道,项目中哪个组件有用到这个变量,有没有在其他组件中进行改变,所以这个api在项目中很少人使用,但是很多人拿来写组件用

在很多开发情况下,我们只是想把组件A的数据传给组件C,如果用props来进行组件通信的话,虽然可以实现,但是代码可读性上不强,且难维护。

所以这时候,我们的主角$attrs$listeners 就出现了

$attrs$listeners 的用法

在vue2.4中,为了解决该需求,引入了$attrs$listeners, 新增了inheritAttrs 选项。 在版本2.4以前,默认情况下父作用域的不被认作props的属性属性百年孤独,将会“回退”且作为普通的HTML特性应用在子组件的根元素上。如下列的例子

父组件的代码:

<template>
  <div>
    <child-dom :foo="foo" :bar="bar"></child-dom>
  </div>
</template>
​
<script>
import ChildDom from "../components/attrs/ChildDom.vue";
export default {
  components: {
    ChildDom,
  },
  data() {
    return {
      foo: "foo",
      bar: "bar",
    };
  },
};
</script>

子组件的代码:

<template>
  <div>
    <p>foo:{{ foo }}</p>
  </div>
</template>
​
<script>
export default {
  props: ["foo"],
};
</script>

我们先看一下这样写的时候,控制台打印出来的dom结构是这样的:

在2.4中新增选项inheritAttrsinheritAttrs的默认值为true, 将inheritAttrs的值设为false, 这些默认的行为会禁止掉。但是通过实例属性 $attrs ,可以将这些特性生效,且可以通过v-bind 绑定到子组件的非根元素上。

将子组件的代码修改一下:

<template>
  <div>
    <p>foo:{{ foo }}</p>
    <p>attrs: {{ $attrs }}</p>
    <dom-child v-bind="$attrs"></dom-child>
  </div>
</template>
​
<script>
import DomChild from "./DomChild.vue";
export default {
  props: ["foo"],
  inheritAttrs: false,
  components: {
    DomChild,
  },
};
</script>

然后在加一个孙组件

<template>
  <div>
    <p>bar:{{ bar }}</p>
  </div>
</template>
​
<script>
export default {
  props: ["bar"],
};
</script>

页面显示如下:

从上面的代码,可以看出使用$attrsinheritAttrs 属性能够使用简洁的代码,将组件A的数据传递给 组件C,该场景的使用范围还是挺广的。

那我们现在来看看组件C怎么传值给组件A?

vue2.4版本新增了$listeners 属性,我们在组件B上 绑定 v-on=”$listeners”, 在组件A中,监听组件C触发的事件。就能把组件C发出的数据,传递给组件A。

修改一下父组件的代码:

<template>
  <div>
    <child-dom :foo="foo" :bar="bar" @upFoo="update"></child-dom>
  </div>
</template>
​
<script>
import ChildDom from "../components/attrs/ChildDom.vue";
export default {
  components: {
    ChildDom,
  },
  data() {
    return {
      foo: "foo",
      bar: "bar",
    };
  },
  methods: {
    update(val) {
      this.foo = val;
      console.log("update success");
    },
  },
};
</script>

子组件代码:

<template>
  <div>
    <p>foo:{{ foo }}</p>
    <p>attrs: {{ $attrs }}</p>
    <dom-child v-bind="$attrs" v-on="$listeners"></dom-child>
  </div>
</template>
​
<script>
import DomChild from "./DomChild.vue";
export default {
  props: ["foo"],
  inheritAttrs: false,
  components: {
    DomChild,
  },
};
</script>

孙组件代码:

<template>
  <div>
    <p>bar:{{ bar }}</p>
    <button @click="startUpFoo">我要更新foo</button>
  </div>
</template>
​
<script>
export default {
  props: ["bar"],
  methods: {
    startUpFoo() {
      this.$emit("upFoo", "foooooooooooo");
      console.log("startUpFoo");
    },
  },
};
</script>

运行结果:

现在我们应该清楚了$attrs$listernersinheritAttrs 的作用了吧

到此这篇关于vue $attrs和$listeners的使用与区别的文章就介绍到这了,更多相关vue $attrs $listeners内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在Vue中使用highCharts绘制3d饼图的方法

    在Vue中使用highCharts绘制3d饼图的方法

    本篇文章主要介绍了在Vue中使用highCharts绘制3d饼图的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • Vue刷新当前组件的五种方式

    Vue刷新当前组件的五种方式

    本文介绍了五种刷新Vue当前组件的方法:使用location.reload()、路由刷新、v-if或key属性、beforeRouteUpdate导航守卫以及$forceUpdate,每种方法都有其适用场景和优缺点,需要的朋友可以参考下
    2025-02-02
  • 如何让vue长列表快速加载

    如何让vue长列表快速加载

    这篇文章主要介绍了如何让vue长列表快速加载,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-03-03
  • 解决vue axios跨域 Request Method: OPTIONS问题(预检请求)

    解决vue axios跨域 Request Method: OPTIONS问题(预检请求)

    这篇文章主要介绍了解决vue axios跨域 Request Method: OPTIONS问题(预检请求),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue mvvm数据响应实现

    vue mvvm数据响应实现

    这篇文章主要介绍了vue mvvm数据响应实现的方法,帮助大家更好的理解和使用vue,感兴趣的朋友可以了解下
    2020-11-11
  • VUE 实现element upload上传图片到阿里云

    VUE 实现element upload上传图片到阿里云

    这篇文章主要介绍了VUE 实现element upload上传图片到阿里云,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Vue中KeepAlive内置缓存使用详解

    Vue中KeepAlive内置缓存使用详解

    KeepAlive 是 vue 中的内置组件,当多个组件动态切换时可以对实例状态进行缓存,本文就来详细的介绍一下Vue中KeepAlive内置缓存使用,感兴趣的可以了解一下
    2023-10-10
  • vue如何根据数值判断颜色

    vue如何根据数值判断颜色

    这篇文章主要介绍了vue如何根据数值判断颜色问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Vue3中Vuex状态管理学习实战示例详解

    Vue3中Vuex状态管理学习实战示例详解

    这篇文章主要为大家介绍了Vue3中Vuex状态管理学习实战示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 详解vue-router基本使用

    详解vue-router基本使用

    本篇文章主要介绍了详解vue-router基本使用,详细的介绍了vue-router的概念和用法,有兴趣的可以了解一下。
    2017-04-04

最新评论