在写项目过程中发现很多组件之间需要通信,父子组件之间还好,但有时就需要跨多级传值,传很多值就很繁琐,代码也很冗余。
在vue文档中我发现这样一个属性,可以将要传递的值放到$attrs中,这样只需要在孙辈组件中取就ok,中间过程中就可以减少很多重复代码。而子辈或者孙辈中emit的事件可以在中间组件中通过$listeners属性避免多于代码。
parents.vue
<template>
<div class="parent">
<child1 :name="name" :uin="uin" :code="code" @test="onTest"></child1>
</div>
</template>
<script lang="ts">
import child1 from '@/components/functional/child1.vue';
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator';
@Component({
name: 'parent',
})
export default class parent extends Vue {
private name: string = '陈黄平'
private uin: string = '320250'
private code: string = 'wxid_ping'
private onTest() {
console.info('从父组件传上来的点击事件')
}
}
</script>
child1.vue
<template>
<div class="child1">
<grand-child v-bind="$attrs" v-on="$listeners" inheritAttrs="false"></grand-child>
/** inheritAttrs="false"是为了避免$attrs中的值被绑定到dom树上,不确定在ts环境下是不是这样的写法 */
</div>
</template>
<script lang="ts">
import grandChild from '@/components/functional/grandChild.vue';
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator';
@Component({
name: 'child1',
})
export default class child1 extends Vue {
@Prop()
private name: string
private created() {
console.info($attrs) /** { “uin”: “320250” ; “code”:“wxid_ping”} */
}
/** $attrs中存放的是未经过prop定义的属性 */
}
</script>
grandChild.vue
<template>
<div class="grandChild">
跨级传值,只需要在最后一级取值就ok,中间级可以避免重复的传值代码
<button @click="onShow">触发事件</button>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator';
@Component({
name: 'grandChild',
})
export default class grandChild extends Vue {
private created() {
console.info($attrs) /** { “uin”: “320250” ; “code”:“wxid_ping”} */
}
/** $attrs中存放的是未经过prop定义的属性 */
private onShow() {
this.$emit('test');
}
}
</script>
这样一些不涉及逻辑操作/简单的跨级传值操作就可以通过$attrs来进行了。