前言
今天在开发的时候,发现同事用到了$attrs和$listeners,因为此前本人用的很少,所以就去研究了一下,总的来说这两个api就是用来进行组件之间通信的,只不过不用像props和$emit传值t通信那样繁琐,缺点就是不好维护,可读性比较低,因此我们在项目中用的比较少,如果需要跨多个组件通信也会选择Vuex
主要内容
- 先来看$attrs和$listeners的定义在Vue文档中:
- vm.$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
- $listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
<template> <div id="app"><Child1 :words1="text1" :words2="text2" :words3="text3" v-on:event1="goEvent1" v-on:event2="goEvent2"></Child1> </div></template><script>import Child1 from "./components/Child1"export default { name: "App", data() {return { text1: 1, text2: 2, text3: 3} }, methods: {goEvent1() { console.log("child 提交成功") },goEvent2(value) { console.log(value) } }, components: { Child1, } }</script><style>html,body { height: 100%; }#app { height: 100%; }</style>复制代码
<template> <div class="mainWrapper"><p>props: {{words1}}</p><p>$attrs: {{$attrs}}</p><button @click="submit()">提交</button><hr><child2 v-bind="$attrs" v-on="$listeners"></child2><!-- 通过$listeners将父作用域中的v-on事件监听器,传入child2,使得child2可以获取到app中的事件 --> </div></template><script>import Child2 from "./Child2"export default { name: "Child1", props: ["words1"], data() {return {} }, inheritAttrs: true, components: { Child2 }, methods: {submit() { this.$emit("event1", "child1 提交事件") } } }</script><style scoped>.mainWrapper { height: 100px; }</style>复制代码
<template> <div><div class="child-2"> <p>props: {{words2}}</p> <p>$attrs: {{$attrs}}</p> <input v-model="inputValue" name="" id="" @input="goInput"></div> </div></template><script>export default { name: 'Child2', props: ['words2'], data() {return { inputValue: ''}; }, inheritAttrs: false, mounted() { }, methods: { goInput () { this.$emit('event2', this.inputValue); } } }</script>复制代码
- Child2.vue
- Child1.vue
- App.vue
- 可以看到父组件App.vue中通过v-bind给Child1传递了三个值,在子组件中未被Props接收的值都在$attrs中,其也可以通过v-bind将值传递给Child1的内部组件Child2,同时也可以使用$listeners将父作用域中的v-on事件监听器,传入child2
- 当一个组件设置了inheritAttrs: false后(默认为true),那么该组件的非props属性(即未被props接收的属性)将不会在组件根节点上生成html属性,以为为对比图
inheritAttrs:false
inheritAttrs:true 复制代码