zoukankan      html  css  js  c++  java
  • vue2.0 slot用法

    学习vue.js也有一段时间了,关于slot这一块,也看了不少次了,总感觉有点迷迷糊糊,不知其然也不知其所以然,抽出一段完整的时间,再一次仔细学习。稍微有点理解了,在此稍作记录,好记性不如烂笔头嘛!

    vue关于实现slot的原因也给与了解释:

    为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为内容分发 (即 Angular 用户熟知的“transclusion”)。
    Vue.js 实现了一个内容分发 API,参照了当前 Web Components 规范草案,使用特殊的 <slot> 元素作为原始内容的插槽。
    

      也就是说slot的主要作用是“内容分发”,所以才实现<slot>元素的,那么究竟什么才是内容分发呢?

      从我个人浅显的理解就是:

        当一个子组件当中,大部分元素是可共用的,只有部分略有差别的时候,这时候就可以通过父组件实现内容分发,从而定制子组件当中略有差别的内容。

      举例来说:

      

    以当前两个页面来说,学校排行和作品排行的列表基本上就是一样,但是不可否认,他们也不完全一样,所以此时如果使用内容分发的话,可能相对能够更简便的吧(当然,使用各自子组件也必然能够实现相同效果)!

    RankSchool.vue和RankWorks.vue两个文件作为父组件,都需要调用RankTable.vue

    先看一下RankTable.vue的内容:

    <template>
      <table>
        <slot name="title"><caption>作品排行</caption></slot>
        <thead>
          <slot name="header"> 
            <tr>
              <th>序号</th>
              <th>姓名</th>
              <th>ID</th>
              <th>学校</th>
              <th>点赞数</th>
            </tr>
          </slot>
        </thead>
        <tbody>
          <slot>
            <tr v-for="(item, index) in items" :key="item.id + index">
              <td>{{index + 1}}</td>
              <td>{{item.name}}</td>
              <td>{{item.id}}</td>
              <td>{{item.school}}</td>
              <td>{{item.praise}}</td>
            </tr>
          </slot>
        </tbody>
      </table>
    </template>
    

      至于里面的数据,暂不考虑,其实子组件文件还是比较简单的,就是子组件的所有内容,唯一的区别之处在于,在有可能做内容分发的地方使用<slot>标签,我们当前文件有三个地方可能产生内容分发,

      <caption>作品排行</caption>

      两个排行榜名称应该是不一样的,所以使用<slot name="title"></slot>将<caption>作品排行</caption>这个标签包裹起来。

      第二处内容分发的地方在table的表头,也就是thead标签。

            <tr>
              <th>序号</th>
              <th>姓名</th>
              <th>ID</th>
              <th>学校</th>
              <th>点赞数</th>
            </tr>
    
    
    

      我们使用<slot name="header"></slot>将这一段包裹。

      还有一处自然是真正的列表部分了,

            <tr v-for="(item, index) in items" :key="item.id + index">
              <td>{{index + 1}}</td>
              <td>{{item.name}}</td>
              <td>{{item.id}}</td>
              <td>{{item.school}}</td>
              <td>{{item.praise}}</td>
            </tr>    
    

      也使用<slot></slot>包裹,允许有匿名的slot,但是为了清晰而言,建议除非当前组件内只有一个slot,否则就将所有slot予以命名。

      由于我们的子组件基本上是以“作品排行”的内容作出来的页面,所以在RankWorks.vue中调用时,就直接调用就好了

    <template>
      <div class="ranking">
        <loading v-if="loading"></loading>
        <rank></rank>
      </div> 
    </template>
    <script>
      import Rank from "./RankTable"
    export default {
      components: {
          Rank
        }
    }
    </script>
    

      简单方便,与正常的组件调用没有任何区别。

      而在“学校排行”组件RankSchool.vue文件中调用的时候,就需要我们注意了,得做好内容分发,不然展现的列表就与“作品排行”一样了。

    <template>
      <div class="ranking">
        <loading v-if="loading"></loading>
        <rank>
          <caption slot="title">学校排行</caption>
          <tr slot="header">
            <th>序号</th>
            <th>学校</th>
            <th>综合得分</th>
          </tr>
          <tr v-for="(item, index) in lists" :key="item.id">
            <td>{{index + 1}}</td>
            <td>{{item.school}}</td>
            <td>{{item.score}}</td>
          </tr>
        </rank>
      </div>
    </template>
    

      其实,也就是在<rank></rank>标签内添加内容,以标签上加slot="名称"来区分当前内容将要分发到子组件哪一个slot当中,如果都没有slot="名称",会将所有内容填充的子组件的<slot></slot>当中,也就是子组件当中匿名的slot当中。

      可以总结出来这么一个简单方法:

      子组件按照平时写组件的习惯写,等到子组件完全写好之后,在父组件调用时,发现哪里需要分发内容的,回到子组件当中,使用<slot name="名称"></slot>将子组件中需要替换的这一部分给包裹起来。是不是很简单呢?

      可能在简单项目,或者多数项目当中,未必需要使用<slot></slot>内容分发,但是掌握<slot></slot>不是也能精简我们的vue文件么?

  • 相关阅读:
    Linux驱动学习时间、延迟及延缓操作3
    Windows 系统下Git安装图解
    [整理]Android Intent和PendingIntent的区别
    C++篇实现MD5算法
    重温数据结构——(2)
    重温数据结构——(1)
    红黑树——1.介绍与查找
    Ubuntu Telnet 服务
    文本框垂直居中
    文本框透明无边框
  • 原文地址:https://www.cnblogs.com/zhuhuoxingguang/p/8421534.html
Copyright © 2011-2022 走看看