A父、B子、C孙
组件传值的时候会用到A组件在B组件传递值,B组件会通过 $attrs获取到不在B组件props里面的所有属性,B组件通过在C组件上绑定 $attrs 和 $listeners 使C组件获取A组件传递的值并且可以调用在A组件那里定义的方法
多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法-- $ attrs/ $listeners
$ attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。
$ listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件 例子:
// A组件
<template>
<div class="home">
<el-link type="primary" @click="change">测试vuex修改参数,其他页面响应式改变</el-link>
<!-- $attrs和$listeners -->
<Son :name="name" @change="change"></Son>
</div>
</template>
<script>
import Son from '@/components/attrsListeners/son.vue'
export default {
name: 'Home',
components: {
Son
},
data() {
return {
params: {},
name: 'suzilong',
aa: '$attrs和$listeners用法'
}
},
computed: {
// ...mapGetters(["sidebar"])
sidebar() {
return this.$store.getters.sidebar
}
},
methods: {
change() {
console.log(this.$store)
// this.params = this.$store.getters.sidebar
this.$store.dispatch("app/sideBar", "hello suzilong")
}
}
}
</script>
B组件:不使用props获取时,可以使用 $attrs获取。当使用props获取时,不可以使用 $attrs获取
//B组件
<template>
<div>
<div>第二级组件</div>
<div>{{ $attrs }}-----$attrs</div> //{ "name": "suzilong" }
<div>{{ $attrs.name }}---第二级组件</div> //suzilong
<div>{{ $attrs.aa}}---第二级组件</div> //undefined
<div>{{ aa }}---第二级组件</div> //$attrs和$listeners用法
<Sun v-bind="$attrs" v-on="$listeners"></Sun>
</div>
</template>
<script>
import Sun from '@/components/attrsListeners/sun.vue'
export default {
name: 'Son',
components: { Sun },
props: {
aa: {
type: String,
default: () => {
return ""
}
}
}
}
</script>
C组件获取A值并调取A组件方法
// C组件
<template>
<div>
<div>第三级组件</div>
<button @click="btn">点击</button>
<div>{{ $attrs }}</div> //{ "name": "suzilong" }
</div>
</template>
<script>
export default {
name: 'Sun',
methods: {
btn() {
//调取A组件的事件
this.$emit("change")
}
}
}
</script>
简单来说:$ attrs与$ listeners 是两个对象,$ attrs 里存放的是父组件中绑定的非 Props 属性,$ listeners里存放的是父组件中绑定的非原生事件
|