[Vue] $attrs的使用场景

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Vue] $attrs的使用场景相关的知识,希望对你有一定的参考价值。

参考技术A 正常情况下,Vue推荐用props向子组件参数。但是在特定场景下,使用 $attrs 会更方便。

考虑最简单的场景,一个滑动输入框组件定义如下:

正常调用它的方式为:

但实际上,我们可以为其额外增加一些属性

这些属性没有在子组件的 props 中,会以原生方式出现在 input 标签中:

由于这里根元素只有一个 <input> ,不需要 $attrs 登场,就能完成属性的传递。

例如父组件不变,子组件换成这样定义:

渲染出来的dom如下:

可以看出,我们额外增加的属性并没有传递给 input .

只需给 input 增加一个指令 v-bind="$attrs"

可以看出,额外增加的属性,又成功的传递给了 input 标签。

Vue2.x $attrs和$listeners

一、非 Prop 的 Attribute($attrs)

参考

  1. 非 Prop 的 Attribute
  2. vm.$attrs API

应用场景

一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 prop 定义的 attribute。

因为显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的 attribute,而这些 attribute 会被添加到这个组件的根元素上

替换/合并已有的 Attribute

  1. 替换——绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值

在这里插入图片描述

如果传入 type=“text” 就会替换掉 type=“date” 并把它破坏

  1. 合并——class 和 style attribute 会稍微智能一些,即两边的值会被合并起来

禁用 Attribute 继承

如果你不希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false

Vue.component('my-component', {
	inheritAttrs: false,
	// ...
})

$attrs

概念说明

  • 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)
  • $attrs 包含了传递给一个组件的 attribute 名和 attribute 值;即一个JSON对象
  • 可以通过v-bind="$attrs"传入内部组件

$attrs 案例

  1. 父组件
<template>
  <SlotContainer
    ref="slotContainer"
    name="huangbiao"
    :isOk="false"
    :option="{ a: 1, b: true, c: 'ddd' }"
  >
  </SlotContainer>
</template>

<script>
import SlotContainer from "./SlotContainer"

export default {
  data() {
    return {};
  },
  components: {
    SlotContainer,
  }
};
</script>

<style lang="scss" scoped></style>
  1. 子组件
<script>
export default {
  data() {
    return {};
  },
  props: {
    option: {
      type: Object,
      default: function() {
        return {};
      }
    }
  },
  mounted() {
    console.log(this.$attrs);
  },
  methods: {}
};
</script>
结果
不注释掉子组件的props, $attrs的值
在这里插入图片描述
注释掉子组件的props, $attrs的值
在这里插入图片描述

inheritAttrs: false 和 $attrs ;配合使用解决的问题?

  1. 可以手动决定这些 attribute 会被赋予哪个元素
  2. inheritAttrs: false 选项不会影响 style 和 class 的绑定
  3. 这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素

二、将原生事件绑定到组件

参考

vm.$listeners

$listeners

概念说明

  • 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
  • 可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素
  • 它是一个对象,里面包含了作用在这个组件上的所有监听器。例如

案例

  1. 父组件
<template>
  <div class>
    <SlotContainer
      ref="slotContainer"
      v-on:m1="m1"
      v-on:m2="m2"
      @m3="m3"
      @m4="m4"
      @click.native="testJiami"
    >
    </SlotContainer>
  </div>
</template>

<script>
import SlotContainer from "./SlotContainer";
import CryptoJS from "crypto-js";
export default {
  data() {
    return {};
  },
  components: {
    SlotContainer,
  },
  methods: {
    testJiami() {
      this.m1();
      this.m2();
      this.m3();
      this.m4();
    },
    m1() {
      console.log("加密结果一 MD5:" + CryptoJS.MD5("你好"));
      // 加盐 对应的API
      console.log("加密结果一 MD5:" + CryptoJS.HmacMD5("你好", "salt"));
      console.log(CryptoJS.SHA256("123456").toString());
      // 加盐 对应的API
      console.log(CryptoJS.HmacSHA256("123456", "salt").toString());
    },
    m2() {
      var pwd = "passwor";
      console.log("加密结果二 Hmac-MD5: " + CryptoJS.HmacMD5("你好", pwd));
    },
    m3() {
      var salt = CryptoJS.enc.Utf8.parse("salt"); //盐
      var iter = 1000; //迭代次数
      var mi = CryptoJS.PBKDF2("你好", salt, {
        keySize: parseInt(4),
        iterations: parseInt(iter),
      });

      console.log("加密结果三:" + mi);
    },
    m4() {
      var pswd = "我的密码";
      var mi = CryptoJS.AES.encrypt("你好", pswd);
      console.log("加密结果四" + mi);
      //解密
      var result = CryptoJS.AES.decrypt(mi, pswd).toString(CryptoJS.enc.Utf8);
      console.log("解密结果:" + result);
    },
  },
};
</script>

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

  1. 子组件(SlotContainer.vue)
<script>
export default {
  data() {
    return {};
  },
  mounted() {
    console.log(this.$listeners);
  },
  methods: {}
};
</script>

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

  1. 结果
    在这里插入图片描述

@click.native="testJiami"的方法没有在 $listeners中

三、思维导图附件

vue2.x a t t r s 和 attrs和 attrslisteners

在这里插入图片描述

以上是关于[Vue] $attrs的使用场景的主要内容,如果未能解决你的问题,请参考以下文章

vue基于 element ui 的按钮点击节流

Vue2.x $attrs和$listeners

Vue2.x $attrs和$listeners

vue组件通信

Vue2 element selection组件设置默认选项

[转] vue中父子组件通信