vue插槽slot的贯彻理解

*在项目中,时不时会遇到一种情况即:在组件标签内再展示一些内容,默认是不会生效的,需要加上<template slot-scope= 'scope'></template>才生效,一直这么稀里糊涂的用,也不太好,故最近翻阅许多书籍并加以实践,最终彻底搞懂其内部流程,特此记录在这

*大白话就不说了,直接进入主题吧

   1、slot是在子组件中写入的,一旦走进组件标签(父组件中引入的子组件)内部,其显示内容的顺序就由组件标签(父组件中引入的子组件)决定

   2、slot插槽显示的内容由父组件进行控制;插槽显示不显示和显示顺序由子组件控制

*以上是总的概括,下面就是代码解释,可能会更清楚一点

  1、匿名插槽

        父组件:父组件在引入的Children子组件里面又放了一堆内容,其这堆内容的显示将会依照子组件内部的顺序依次执行显示

<template>
  <div class="hello">
    <p>第一个显示的</p>
    <Children>
      <p>第三个显示的</p>
      <p>第四个显示的</p>
      <chilchildren></chilchildren>
      <p>第五个显示的</p>
    </Children>
  </div>
</template>

<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'

export default {
  components: {
    Children,
    chilchildren,
  },
}
</script>

        子组件: 此组件放了二个匿名插槽,意味着将在父组件里面引入的子组件内部的内容显示两次

<template>
  <div class="slotOne">
    <p>第二个显示的</p>
    <slot></slot>
    <p>第六个显示的</p>
    <!-- 注意这里又放了一个匿名插槽,意味着将在父组件里面引入的子组件内部的内容显示两次 -->
    <slot></slot>
    <p>第七个显示的</p>
  </div>
</template>

        效果图:其中红框圈出的两部分就是子组件定义的两个slot

        

2、具名插槽

      父组件:使用v-slot或者#(是v-slot的缩写)或者slot(v3.0已废弃这种写法)来对应子组件的某个插槽

<template>
  <div class="hello">
    <p>第一个显示的</p>
    <Children>
      <!-- <template v-slot:one> v-slot和#只能在template中写入-->
      <template #one>
        <p>第三个显示,因为对应子标签name为one的slot</p>
      </template>
      <p>
        特别注意:因为在子标签没有对应的匿名slot,故这下此内容和下面的子子标签就不会显示了
      </p>
      <chilchildren></chilchildren>
      <p slot="two">第五个显示,因为对应子标签name为two的slot</p>
    </Children>
  </div>
</template>

<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'

export default {
  components: {
    Children,
    chilchildren,
  },
}
</script>

      子组件:使用name属性来区分各个插槽,方便在父组件进行调用

<template>
  <div>
    <p>第二个显示的</p>
    <slot name="one"></slot>
    <p>第四个显示的</p>
    <slot name="two"></slot>
  </div>
</template>

    效果图: 

       父组件:

<template>
  <div class="hello">
    <p>第一个显示的</p>
    <Children>
      <template slot="one">
        <p>第三个显示,因为对应子标签name为one的slot</p>
      </template>
      <p>
        第五个显示的,特别注意:因为在子标签有了相对应的匿名slot,故这下此内容和下面的子子标签就显示了
      </p>
      <chilchildren></chilchildren>
      <p slot="two">第七个显示</p>
    </Children>
  </div>
</template>

<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'

export default {
  components: {
    Children,
    chilchildren,
  },
}

     子组件:

<template>
  <div>
    <p>第二个显示的</p>
    <slot name="one"></slot>
    <p>第四个显示的</p>
    <slot></slot>
    <slot name="two"></slot>
  </div>
</template>

     效果图:

 3、作用域插槽

       此时就映射到我们的slot-scope="scope"了

       父组件接收子组件的值是用slot-scope进行接收,此时scope的名字可以为任意,它默认就是一个对象,会拿到子组件data中的所有数据

        父组件:

<template>
  <div class="hello">
    <Children>
    <!--  anyName默认可以随便起名字,它默认是一个对象,获取到的是Children组件中的data总数据,用它anyName.importData取出user数据 -->
      <template slot-scope="anyName">
        <p v-for="(item, index) in anyName.importData" :key="index">
          {
   
   { item }}
        </p>
      </template>
    </Children>
  </div>
</template>

<script>
import Children from '@/components/children'

export default {
  components: {
    Children,
  },
}
</script>

       子组件:

<template>
  <div>
    <!-- importData待会父组件就可以用它来获得到user数据 -->
    <slot :importData="user"></slot>
  </div>
</template>

<script>
export default {
  components: {},
  name: '',
  data() {
    return {
      user: [
        { name: '小小', age: 18 },
        { name: '大大', age: 18 },
        { name: '呼呼', age: 18 },
      ],
    }
  }
</script>

      效果图:

 

好啦,结束,言简意赅!! 

猜你喜欢

转载自blog.csdn.net/du111_/article/details/109136986
今日推荐