本文的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这些原生/自定义属性)

 

 

 

Logo

前往低代码交流专区

更多推荐