vue 高阶组件必备知识$attrs,inheritAttrs,$listenters详解
pencil-690050_1920.jpg
1,inheritAttrs详情
vue默认情况下,父组件是可以直接给子组件的根元素增加class和style的,但是有时候我们可能需要在父组件上给子组件增加少量特性绑定(attribute bindings)(我的了解是自己设置属性和少量原生属性)到子组件的根元素上,inheritAttrs就是用来控制子组件根元素上能否允许增加父组件在子组件上定义的特性属性,由于inheritAttrs默认为true,所以我们在父组件中给子组件增加所有特性绑定,都能绑定到根元素,例如下面
<template><div> <base-item class="box" key="1" default-id="1" style="font-size: 14px;"> </base-item></div></template><script>export default { components: { baseItem: { inheritAttrs: false, template: ` <div> <span>good</span> </div> ` } }}</script>渲染后的dom节点:
<div default-id="1" class="box" style="font-size: 14px;"> <span>good</span> </div>把inheritAttrs设为false后,
渲染后的dom节点:
<div class="box" style="font-size: 14px;"> <span>good</span> </div>可以得出上述的结论,inheritAttrs是用来控制子组件根元素上能否允许增加父组件在子组件上定义的特性属性。
注意:
inheritAttrs是用来控制父组件中传递的特性属性,class和style不是特性属性,不能用inheritAttrs来控制。
2,$attrs详情
我们可以把父作用域中传递的所有属性看作一个大的对象obj,而$attrs会继承obj中的一部分属性,这一部分属性的key不能为class,和style,也不能是当前组件公告的props值,并且父组件为v-model的话,也是不能继承指令封装的value值的,若当前组件无props设置,$attrs则继承除class和style的所有属性。
通常我们给已封装的组件进行中间解决的时候使用,例如element-ui的el-input,我们需要把父组件中的传递的props直接给子组件的子组件的时候,我们即可以用到$attrs,例如:
父组件为:
<self-input class="self-input" :limit="2" v-model="item.count" count="234"></self-input>子组件为:
<el-input type="text" v-bind="$attrs" v-model="defaultValue"> </el-input>export default { props: {limit: Number}}根据上面所说,去掉class,去掉指定的value,去掉子组件props公告的limit,那时我们此的$attrs是:
{ count: '234'}3,$listenters详情
我们对ui框架中的组件进行再封装的时候,例如element-ui中的组件el-input,我们把他封装到我们自己的组件内部。
例如self-input组件如下,
<div> <el-input></el-input></div>我们需要把el-input组件上自己设置的事件传递进去,那么就要用到$listenters。
官网的形容:
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创立更高层次的组件时非常有用。
很容易了解,.native是给子组件根元素增加事件,自然不是用来传给子组件上的子组件或者元素。而我们在父组件上给子组件绑定的所有事件,都会放入$listeners中,我们可以在子组件中手动过滤修改后传给子组件中的子组件或者者元素上,也可以用v-on="$listeners",直接一律传给子组件或者者元素上。
用法也相当简单,例如:
父组件:
<template> <self-input @change="changeHandler" @input="inputHandler" v-model="count"> </self-input></template><script> export default { data () { return {count: ''} }, methods: { changeHandler () {}, inputHandler () {} }}</script>子组件:
<template> <el-input v-on="$listeners" v-model="defaultValue"> </el-input></template><script>export default { data () { return { defaultValue: '' } }, props: { value: [String, Number] // value值 }, mounted () { console.log(this.$listeners) }}</script>因为父组件传入的是一个change事件和两个input事件,那我们打印的this.$listeners是
{ change: fn, input: [fn, fn]}下面是一个关于限制小数点的完整demo,感兴趣的可以理解一下
<template> <el-input ref="input" type="text" v-bind="$attrs" v-on="$listeners" @input.native="inputHandle" v-model="defaultValue"> </el-input></template><script>/** 示例 当前组件主要目的是实时控制输入框小数点右侧字符长度 * <self-input * :minLimit="0.21" :maxLimit="100.22" * @input="inputHandle" * :limit="2" v-model="aaa"></self-input> * limit 小数点有几位 * 解释 * v-model的作用是将value和事件传递给子组件el-input,并且作为中间变量来传递value值 * inputHandle 主要是对输入的内容进行实时校验 */export default { data () { return { defaultValue: '' // 作为中间变量 } }, inheritAttrs: false, // 此处设置根元素禁用继承特性(只继承class属性) // 当inheritAttrs为true的话,只继承除class style props之外的属性 props: { limit: { // 小数点保留位数 type: Number, required: true }, // 小数点长度 maxLimit: Number, // 最大数值 minLimit: Number, // 最小数值 value: [String, Number] // value值 }, watch: { value: { handler (val) { this.defaultValue = val }, immediate: true // 给组件设置默认值 } }, methods: { inputHandle (e) { let val = e.target.value || '' if (!val) { val = this.defaultValue } this.formatNumber(val) }, formatNumber (val) { val = String(val).replace(/e/, '') // 替换e为空 if (/\./.test(val)) { // 控制小数点位数 // 替换掉小数点后面的点和非数字 let str = val.split('.')[1].replace(/\./g, '').replace(/\D/g, '') val = val.split('.')[0] + '.' + str.substr(0, this.limit) } else { val = String(val).replace(/\D/g, '') } // 判断能否超过最大值 if (this.maxLimit && Number(val) >= this.maxLimit) { val = String(this.maxLimit) } // 判断能否小于最小值 不等于0的目的是为了可以删除所有 if (this.minLimit && Number(val) !== 0 && Number(val) <= this.minLimit) { val = String(this.minLimit) } this.defaultValue = val this.$refs.input.currentValue = val this.$emit('input', val) } }, mounted () { console.log(this.$listeners) }}</script><style lang="scss" scoped></style>1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » vue 高阶组件必备知识$attrs,inheritAttrs,$listenters详解