img

vue中 $attrs 和 $listeners 的作用

2022-09-01 0条评论 1.9k次阅读 JavaScript


$attrs

概念:
$attrs: 包括组件 props 和 emits property 中未包含的所有属性 (例如,class、style、v-on 监听器等)

ps: 官网原话
其实就可以简单理解为:除了组件内props声名了的所有给组件传的值(class,style除外)

这个属性有什么作用呢?

当我们需要给多层嵌套父子组件传值,而且杂的时候,可以直接使用它,可以使代码看起来更加简洁。案例如下:

// parent.vue
<m-child :data-status="dataStatus" :data-message="dataMessage"></m-child>

<script>
export default {
    data(){
        return {
            dataStatus: '123',
            dataMessage: '456'
        }
    }
}
</script>
// m-child.vue
<m-grandron v-bind="$attrs"></m-grandron>
<script>
export default {
    props:{
        dataStatus: String,
    },
    data(){
        return {}
    },
    created(){
        console.log('dataStatus',this.dataStatus)  //  123
        console.log('dataMessage',this.dataStatus)  //  456
    }
}
</script>
// m-grandron.vue
export default {
    data(){
        return {}
    },
    created(){
        console.log('dataStatus',this.$attrs)  //  {dataMessage:456} 因为child组件中props声名了dataStatus所以这里$attrs就不含有dataStatus
    }
}

如果我们按常规的props传值,就要一层一层传,层级多了就很恶心,使用$attrs就很轻松的做到了。

注意:
当又给m-grandron组件传了和$attrs内属性同名的值时,值会被覆盖(使用传入的值)。 如下:

// m-child.vue
<m-grandron v-bind="$attrs" data-message="789"></m-grandron>
<script>
export default {
    props:{
        dataStatus: String,
    },
    data(){
        return {}
    },
    created(){
        console.log('dataStatus',this.dataStatus)  //  123
        console.log('dataMessage',this.dataStatus)  //  456
    }
}
</script>
// m-grandron.vue
export default {
    data(){
        return {}
    },
    created(){
        console.log('dataStatus',this.$attrs)  //  {dataMessage:789} 因为child组件中props声名了dataStatus所以这里$attrs就不含有dataStatus,因为传的dataMessage和$attrs内同名,所以值被覆盖变为789
    }
}

$listeners

$listeners: 接收除了带有.native事件修饰符的所有事件监听器作用和上述类同。

有一点不同的是:当出现同名的事件时,不会被覆盖,而是都会执行,执行顺序就是事件冒泡的执行顺序,先触发child 再触发parent

案例如下:

// parent.vue
<m-child @customEvent="ev_customEvent"></m-child>
<script>
export default {
    data(){
        return {
            dataStatus: '123',
            dataMessage: '456'
        }
    },
    methods:{
        ev_customEvent(){
            console.log('my name is parent!')
        }
    }
}
</script>

// m-child.vue
<m-grandron v-on="$listeners" @customEvent="ev_customEvent"></m-grandron>
<script>
export default {
    props:{
        dataStatus: String,
    },
    data(){
        return {}
    },
    methods:{
        ev_customEvent(){
            console.log('my name is child!')
        }
    }
}
</script>

// m-grandron.vue
<button @click="$emit('customEvent')">click me!</button>
<script>
export default {
    data(){
        return {}
    },
}
</script>


// 控制台
// my name is child!
// my name is parent!

使用$listeners 属性可以很方便的在层级很深的组件内,立马就修改最外层的父组件内的属性值。

注意:在vue3.0 中$listeners被移除了,将所有属性都集合到attrs里面了

本文转自 https://blog.csdn.net/qq_41709082/article/details/120725561, 如有侵权,请联系删除。

💬 COMMENT


🦄 支持markdown语法

👋友