prop,具名作用域插槽,多层组件attr和listener透传

Vue prop(父组件给子组件传参)和作用域插槽(子组件环境可在父组件的插槽内用)

Vue prop:
Array和Object的default要向data一样用return的方式initialize
如果父组件绑定在子组件的变量发生更新,子组件通过watch方式检测变化然后进行改动
prop属性名要用kebab-case,因为html不区分大小写

//父组件
<sFundhisflot1
    :adjust-info="adjustInfo"   //kebab-case
></sFundhisflot1>

//子组件
props: {
    adjustInfo: {   //object和array都要用return的方式initialize default
        default: () => [],
        type: Array
    }
},
watch: {
    adjustInfo(newVal) {    //watch来检测父组件的adjustInfo的变化
        //do somthing
    }
},

作用域插槽:
父组件想让子组件的slot显示子组件的user对象的的firstName属性,但是父组件无法直接访问子组件的数据。那么子组件一个将 user 作为 元素的 attribute 绑定上去,让 user 在父级的插槽内容中可用

    //父组件
    具名插槽v-slot:firstName(template内容插到子组件的<slot name="firstName" />)
    作用域插槽v-slot:firstName="slotProps"(firstName插槽里v-bind的props可以在父组件通过slotProps访问),可以简写成#firstName="slotProps"
    <current-user>
        <template v-slot:firstName="slotProps">
            {{ slotProps.user.firstName }}
        </template>
    </current-user>

    //子组件,通过在slot上添加v-bind将user传给给父组件
    <span>
        <slot name="firstName" v-bind:user="user"></slot>
    </span>

理解 v-slot:activator="{ on, attrs }"
将activator slot组件的attrs和on作用域给父组件,使得父组件可以使用它的props和event。

v-bind="attrs"vbind="attrs"和v-bind="props",v-on="$listeners" 和.native 多层组件透传

将在高层组件v-on上注册的事件监听,和v-bind的没有被中间层识别(并获取)的属性和事件,一步步往下探,供底下的组件可用。如果中间层组件识别了事件和属性,该层可以使用这些事件和属性,但是下层就不能再用了。好处是不用props一层一层传了。

v-bind="attrs"tagvbind="attrs": 父组件tag上绑定的属性 v-bind="props":如果想把父组件的props传给子组件,还可以这样,子组件在props中接收
v-on="$listeners":父组件tag上绑定的非.native修饰符的事件
.native:让事件仅在native处有效,信托h-textfield-advance用到了@click.native="",那么@click事件就不会传给下面了

例子:
top组件,提供attrsname,age,gender,foo,attrs有name,age,gender,foo,listeners有isClick和bar。

<template>
  <section>
    <centers
      name="name"
      age="18"
      gender="666"
      foo="foo"
      @isClick="isClick"
      @bar="bar"
    ></centers>
  </section>
</template>

center组件,吃掉属性name和age,没被吃掉的属性和事件会继续往下传。

<template>
  <section>
    <div class="mt-10">
      <bottom v-bind="$attrs" v-on="$listeners" />
    </div>
  </section>
</template>

<script>
  export default {
    props: {
      name: {
        type: String,
        default: 'default'
      },
      age: {
        type: String,
        default: 'default'
      }
    }
  };
</script>

bottom组件,属性gender和事件isClick和bar,没有被center组件吃掉,所以在bottom组件中依然可用

<template>
  <section>
    <div>
      {{ $attrs['gender'] }} 
    </div>
  </section>
</template>

<script>
  export default {
    mounted() {
      this.$listeners.isClick();
      this.$listeners.bar();
    }
  };
</script>

参考资料:
https://www.cnblogs.com/jin-zhe/p/13099416.html

$slots 父组件使用了哪些插槽

父组件使用子组件,并插入foo和bar槽

<child>
      <slot name="foo" slot="foo"></slot>
      <slot name="bar" slot="bar"></slot>
</child>

子组件判断是否有这些插槽,如果有blah blah blah
$slots打印出来有foo和bar两个Vnode

<div v-if="$slots.foo" slot="foo">
    <!-- something here --  >
</div>