Vue——$attrs和$listeners
$attrs
Vue2官方文档的解释如下:
作用
简单来说就是 组件向下传递数据 的,是props通信的补充方案,避免了组件中props过多的窘境。
使用场景
在孙子或更深层后代组件访问祖辈组件中的数据
使用
祖父组件GrandPa如下:
传给Parent组件的数据有name,age, gender
<template>
<div>
我是祖父: 下面是爸爸
<Parent v-bind="$attrs" :name="'佩奇爸爸'" :age="age" :sex="sex" />
</div>
</template>
<script>
import Parent from "./Parent.vue"
export default {
name: "GrandPa",
components: {
Parent
},
data() {
return {
age: 65,
sex: '男'
}
}
}
</script>
父亲组件Parent如下:
Parent组件中定义的props只有name
<template>
<div>
我是爸爸:叫 {{ name }}, 下面是儿子
<Son :name="'佩奇'" />
</div>
</template>
<script>
import Son from "./Son.vue"
export default {
name: "Parent",
components: {
Son
},
props: {
name: {
type: String,
default: ""
}
},
data() {
return {
age: 40,
gender: '男'
}
},
created() {
console.log(this.$attrs);
}
}
</script>
GrandPa传进来的age和gender在哪儿?嗯,就在$attrs里,created中打印的 $attrs 如下
{ age: 65, gender: "男" }
上面演示的是父组件不通过props向子组件传递数据,除了这种还可以使用$parent直接访问父组件数据
儿子组件Son如下:
<template>
<div>
我是儿子:叫{{ name }}
</div>
</template>
<script>
export default {
name: "Son",
props: {
name: {
type: String,
default: ''
}
},
data() {
return {
age: 18,
sex: '男'
}
},
created() {
console.log(this.$attrs);
}
}
</script>
定义的props只有name,如果要通过$attrs访问父组件数据,在父组件使用Son组件时吧数据传进来即可,那如果要访问祖父组件GrandPa的数据呢?在Parent组件中使用儿子组件时加上 v-bind=" $attrs "
即可。
<template>
<div>
我是爸爸:叫 {{ name }}, 下面是儿子
<Son v-bind="$attrs" :name="'佩奇'" />
</div>
</template>
如果数据要往更深层组件使用 v-bind=" $attrs "
逐层传递即可。
$listeners
官方文档解释如下:
作用
简单来说就是组件跨代传递函数的桥梁
使用场景
在孙子或更深层后代组件访问祖辈组件中定义的函数
使用
祖辈组件如下:
<template>
<div>
我是祖父: 下面是爸爸
<Parent @printGrandPaAge="printGrandPaAge" />
</div>
</template>
<script>
import Parent from "./Parent.vue"
export default {
name: "GrandPa",
components: {
Parent
},
data() {
return {
age: 65,
}
},
methods: {
printGrandPaAge() {
console.log(this.age);
}
}
}
</script>
祖辈组件中定义了printGrandPaAge方法,同时监听了关键字printGrandPaAge作为子代触发该方法的条件
parent组件如下:
<template>
<div>
我是爸爸: 下面是儿子
<Son v-on="$listeners" />
</div>
</template>
<script>
import Son from "./Son.vue"
export default {
name: "Parent",
components: {
Son
},
data() {},
}
</script>
使用 v-on=" $listeners "
即可把祖辈定义的方法传递到子组件Son中
子组件Son如下:
<template>
<div>
我是儿子:
<el-button @click="test">打印祖父的年龄</el-button>
</div>
</template>
<script>
export default {
name: "Son",
data() {},
methods: {
test() {
this.$emit("printGrandPaAge")
}
}
}
</script>
在Son组件中使用printGrandPaAge关键字即可调用父组件函数