[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)
参考
应用场景
一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 prop 定义的 attribute。
因为显式定义的 prop 适用于向一个子组件传入信息,然而组件库的作者并不总能预见组件会被用于怎样的场景。这也是为什么组件可以接受任意的 attribute,而这些 attribute 会被添加到这个组件的根元素上
。
替换/合并已有的 Attribute
- 替换——绝大多数 attribute 来说,从外部提供给组件的值会替换掉组件内部设置好的值
如果传入 type=“text” 就会替换掉 type=“date” 并把它破坏
- 合并——
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 案例
- 父组件
<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>
- 子组件
<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 ;配合使用解决的问题?
- 可以手动决定这些 attribute 会被赋予哪个元素
- inheritAttrs: false 选项不会影响 style 和 class 的绑定
- 这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素
二、将原生事件绑定到组件
参考
$listeners
概念说明
- 包含了
父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
。 - 可以配合
v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素
- 它是一个对象,里面包含了作用在这个组件上的所有监听器。例如
案例
- 父组件
<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>
- 子组件(SlotContainer.vue)
<script>
export default {
data() {
return {};
},
mounted() {
console.log(this.$listeners);
},
methods: {}
};
</script>
<style lang="scss" scoped></style>
- 结果
@click.native="testJiami"的方法没有在 $listeners中
三、思维导图附件
以上是关于[Vue] $attrs的使用场景的主要内容,如果未能解决你的问题,请参考以下文章