携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
$attrs和$listeners可用于组件间的通信。
$attrs
包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。
当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
官网地址:cn.vuejs.org/v2/api/#vm-…
在孙组件中,使用父组件的数据,子组件只是一个传递数据的中间件,此时可使用$attrs传值。
步骤:父组件中子组件绑定需要传递的数据->在子组件中不再用props接收来自父组件的数据->在子组件中调用孙组件,并绑定$attrs->在孙组件就能直接获取父组件中绑定的值(class 和 style 除外)。
若子组件使用props接收部分值,则该部分值就不能通过$attrs传递给孙组件。
$attrs用于记录从父组件传入子组件的所有不被props捕获以及不是class与style的数据。
父组件:
父组件中,给子组件绑定需要传递的值。未绑定的值则不能传递下去,如数据dataList。
<template>
<div>
<h1>这是父组件</h1>
<!-- 给子组件关联数据,子组件如果不用props接收,那么这些数据就作为普通的HTML特性应用在子组件的根元素上。 -->
<son-component :dataOne="dataOne" :dataTwo="dataTwo" :dataObj="dataObj"></son-component>
</div>
</template>
<script>
import sonComponent from '@/components/sonComponent';
export default {
name: 'oneComponent',
components: { sonComponent },
data() {
return {
dataOne: '父组件-数据1',
dataTwo: '父组件-数据2',
dataObj:{
name: '父组件',
address: '来自于父组件'
},
dataList: {
value: 'dataList'
}
};
},
methods: {
},
mounted() {
},
};
</script>
<style lang="less" scoped>
</style>
子组件:
子组件中,给孙组件添加v-bind="$attrs",子组件不用props接收的值,则会通过$attrs传递给孙组件,如数据dataOne就是props接收了,所以就不能通过$attrs传递给孙组件。
<template>
<div>
<h1>这是子组件</h1>
<!-- 若子组件使用props接收,则不会通过$attrs传递给孙组件 -->
<span>props: {{ dataOne }}</span>
<!-- 给孙组件绑定$attrs,才能将父组件的数据传递下去。 -->
<grandson-component v-bind="$attrs"></grandson-component>
</div>
</template>
<script>
import grandsonComponent from "@/components/grandsonComponent";
export default {
name: 'sonComponent',
components: { grandsonComponent },
props: {
dataOne: "",
},
data() {
return {};
},
methods: {},
mounted() {
console.log("子组件$attrs的值",this.$attrs);
},
};
</script>
<style lang="less" scoped>
</style>
孙组件:
使用孙组件直接使用$attrs的值。
<template>
<div>
<h1>这是孙组件</h1>
<span>
$attrs:{{ $attrs }}
</span>
</div>
</template>
<script>
export default {
name: "grandsonComponent",
data() {
return {};
},
methods: {},
mounted() {
console.log("孙组件$attrs的值",this.$attrs);
},
};
</script>
<style lang="less" scoped>
</style>
父->子->孙:
注意:
父->子:需要在子组件上关联需要传递的数据。
子->孙:需要给孙组件绑定$attrs。
$listeners
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
官网地址:cn.vuejs.org/v2/api/#vm-…
步骤:在父组件中定义事件,子组件监听事件->在子组件中的孙组件添加v-on="$listeners"->孙组件触发事件
父组件:
定义事件,并在子组件上监听事件。
<template>
<div>
<h1>这是父组件</h1>
<son-component @methodOne.native="methodOne" @methodListeners="methodListeners"></son-component>
</div>
</template>
<script>
import sonComponent from '@/components/sonComponent';
export default {
name: 'oneComponent',
components: { sonComponent },
data() {
return {
};
},
methods: {
// 定义父组件方法
methodListeners(value){
console.log('触发了父组件中的methodListeners方法',value);
},
methodOne(value){
console.log('触发了父组件中的methodOne方法',value);
}
},
mounted() {
},
};
</script>
<style lang="less" scoped>
</style>
子组件:
在孙组件上使用v-on="$listeners"。
<template>
<div>
<h1>这是子组件</h1>
<grandson-component v-on="$listeners"></grandson-component>
</div>
</template>
<script>
import grandsonComponent from "@/components/grandsonComponent";
export default {
name: 'sonComponent',
components: { grandsonComponent },
data() {
return {};
},
methods: {},
mounted() {
this.$emit('methodListeners','子组件')
this.$emit('methodOne','子组件')
},
};
</script>
<style lang="less" scoped>
</style>
孙组件:
使用$emit触发父组件中非.native修饰的事件。
<template>
<div>
<h1>这是孙组件</h1>
</div>
</template>
<script>
export default {
name: "grandsonComponent",
data() {
return {};
},
methods: {},
mounted() {
this.$emit('methodListeners','孙组件')
this.$emit('methodOne','子组件')
},
};
</script>
<style lang="less" scoped>
</style>
可以发现,在子和孙组件触发事件时,.native修饰器的事件是不会被触发的。