小言_互联网的博客

Vue2.x $attrs和$listeners

324人阅读  评论(0)

一、非 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


转载:https://blog.csdn.net/hbiao68/article/details/117380984
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场