2023年10月14日

1、在子组件通过props接收父组件的传值的时候,会接收对象,这个对象的默认值为一个函数返回的一个对象。因为,若是对象的话,组件会共享默认值,另个组件同名的对象一旦发生变化,会对这个对象的值进行修改。

// 错误写法
cha: {
    type: Object,
    default: {name: 'zbb'}
}

 // 正确写法:
 cha: {
     type: Object,
     default: () => ({name: 'zbb})
 }

2、数组也是如此

cha: {
    type: Array,
    default: () => ['你', '好']
}

3、非props的attribute。通常使用的属性包括class,styleid属性。你可以通过$attrs来访问它们。

   // 若在父组件里面添加非props的attribute,则该属性会默认添加到组件的根元素。如下,在父元素中的子组件show-info中添加address和class属性,则子组件会在编译后进行渲染。
   <template>
       <show-info address="安庆市" class="cha"></show-info>
   </template>
  
  // 子组件
  <div :class="$attrs.class">
      你好
  </div>
  
  注意:若有多个节点的话,需要通过v-bind对$attrs进行绑定
  <template>
     <div class="test">
        <h2>test</h2>
     </div>
     <div class="test" v-bind="$attrs">
        <h2>test</h2>
     </div>
  </template>

子组件在浏览器中显示的是:

Snipaste_2023-10-14_10-11-28.png

4、父传子的一个注意事项

<tab-tit :titCont="tit"></tab-tit>
在这段代码中,titCont是子组件通过props接收的值,而tit是父组件传给子组件的值

5、插槽

  • 出现背景:父组件可以通过传递数据给子组件,子组件通过props进行接收。但是它只能传递数据,对于像元素不能进行传递,为了增强组件的通用性,插槽随机产生。
  • 写法
// 默认插槽(就一个插槽)

// 父组件parent
<child></child>
默认插槽情况下,这里也可以写成:
<child>
    <template #default></template>
</child>

// 子组件Child
<div>
    <slot>我是插槽</slot>  这里可以添加默认的内容,当父组件没有传内容的时候默认显示
</div>


当父组件里的
<child>
    <button>我是按钮组件</button>
</child>

这时候
<div>
    <slot>我是插槽</slot>
</div>

这里的slot将被 <button>我是按钮组件</button> 所替代。


// 具名插槽(多个插槽)

// 父组件
<MultipleSlot>
  <template #left>
    <button>左边插槽</button>
  </template>
  <template #middle>
    <button>中间插槽</button>
  </template>
  <template #right>
    <button>右边插槽</button>
  </template>
</MultipleSlot>

注意:这里要注意<template #right>是vue2.6版本之后的写法,之前写法为<template v-slot:right>

// 子组件
<div class="left">
  <slot name="left">我是左边</slot>
</div>
<div class="middle">
  <slot name="middle">中间</slot>
</div>
<div class="right">
  <slot name="right">右边</slot>
</div>


// 动态插槽名
通过v-slot:[dynamicSlotName]方式动态绑定一个名称。
  • 渲染作用域

    • 父级模板里的所有内容都是在父级作用域中编译的;
    • 子模板里的所有内容都在子作用域中编译的;
  • 作用域插槽:鉴于渲染作用域,父组件的插槽无法直接访问子组件的数据,此时需要通过作用域插槽的方式先通过子组件将数据传递给父组件,然后再将接受到的数据通过具名插槽传递给子组件。

// 父组件
<template v-slot:test="props">
    <button>{{ props.item }}</button>
</template>

注意:在vue2.6版本之前写法是这样
<child>
    <template slot-scope="slotsProps"> 
        {{slotsProps.info}} 
    </template>
</child>

  
// 子组件
<div>
    <template v-for="item in Arr">
        <slot name="test" :item="item"></slot>
    </template>
</div>