Vue的父子通讯和v-bind=“$props“和v-bind=“$attrs“

本文的VUE例子为typescript vue。

父子通讯

父组件通过props向子组件传值,子组件通过$emit向父组件传值

// Father.vue

<template>
    <div>
        <child :msg='msg' @receive='receiveMsg'></child>
    </div>
</template>
<script>
    ...
    msg = '123'
    receiveMsg(msg) {
        this.msg = msg;
    }
</script>
// Child.vue
<template>
    <div>
        <h1 @click="sendMsg">
            {{msg}}
        </h1>
    </div>
</template>
<script>
    ...
    @Prop({ type: String }) msg;
    sendMsg() {
        this.$emit('receiveMsg','321')
    }
</script>

这是最简单最常见的传讯方式。

父子孙通讯

从父元素开始传递下去的属性可以在子孙等深层的组件作用域里拿到

// Father.vue

<template>
    <div>
        <child :msg='msg' @receive='receiveMsg'></child>
    </div>
</template>
<script>
    ...
    msg = '123'
    receiveMsg(msg) {
        this.msg = msg;
    }
</script>
// Child.vue
<template>
    <div>
        <h1>
            {{msg}}
        </h1>
        <grandChild v-bind="$props"></ChildOne>
    </div>
</template>
<script>
    ...
    @Prop({ type: String }) msg;
</script>
// grandChild.vue
<template>
    <div>
        <h1>
            {{msg}}
        </h1>
        <grandGrandChild v-bind="$props"></ChildOne>
    </div>
</template>
<script>
    ...
    @Prop({ type: String }) msg;
</script>
// grandGrandChild.vue
<template>
    <div>
        <h1>
            {{msg}}
        </h1>
        <grandGrandGrandChild v-bind="$props"></ChildOne>
    </div>
</template>
<script>
    ...
    @Prop({ type: String }) msg;
</script>

通过上面我们可以发现
【v-bind="$props"】可以将自身声明(接收到的)的所有props传递给它的子组件,子孙组件只需要像父子通讯一样使用@props来接收参数就好了。

请注意父子孙组件通讯不要用v-bind="$props",因为它需要在层层组件里声明自己的props,用provide和inject比较好(后续推文会写到)

v-bind="$props"和v-bind="$attrs"

从上面的例子我们可以知道v-bind="$props"可以自身声明(接收到的)的所有props传递给它的子组件。

那么v-bind="$attrs"可以做什么呢?

 在一个组件里,this.$attr当前组件身上绑定的所有属性(不考虑声明了组件内prop的话)

这么说可能很难理解,来看例子

// index.vue
<template>
   <div>
      <child :name="testName" data-name="TEST001" />
    </div>
</template>
<script>
    ...
    testName = 'Test101';
</script>
// child.vue
<template>
  <div>
    <grandChild v-bind="$attrs" />
  </div>
</template>
<script>
    // 不声明prop
</script>

 child.vue的$attrs为:

// grandChild.vue
<template>
  <div>123</div>
</template>
<script>
  ...
  created() {
    console.log(this.$attrs);
  }
</script>

 grandChild.vue的$attrs仍为:

由此可见 index.vue上给child组件定义的name属性和dataName属性都被带过去了,也就是说$atrrs囊括了组件身上绑定的所有属性,此时我们再修改一下:

// child.vue
<template>
  <div>
    <grandChild v-bind="$attrs" />
  </div>
</template>
<script>
   ...
   @Prop() name;
</script>

只修改child,可以看见:

可以看见child.vue的$attrs属性里少了name,而props多了name

grandchild接收到的attrs也只有data-name了

如果我们再改一下

// child.vue
<grandChild v-bind="$props" />

结果一样是吧,为什么呢,因为grandchild没有使用prop来承接它,我们再改一下

<template>
  <div>3333</div>
</template>
<script>
export default class grandChild extends Vue {
  @Prop() name;
}
</script>

 

$attrs变成$props了

看到这里,大概看出v-bind="$props"和v-bind="$attrs"有什么区别了吧.其实就是往子组件里传的参数不同,一个传的是vm.props一个传的是vm.attrs。而组件的attrs其实就是除了本组件声明的prop属性之外的其他绑定在本组件上的属性(可以是vue的动态绑定属性或者name type这些原生/自定义属性)

 

 

 

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值