Vue - 4 - 組件化 - 插槽(slot)

在這裏插入圖片描述

slot

# 爲什麼使用 slot

  • slot 翻譯爲 插槽

在這裏插入圖片描述

  • 插槽的目的是讓我們原有的設備具備更多的擴展性(類java接口?)

功能和實現分離 - 複用+解耦

栗子:移動網站中的導航欄。

  • 移動開發中,幾乎每個頁面都有導航欄。
  • 導航欄我們必然會封裝成一個插件,比如nav-bar組件。
  • 一旦有了這個組件,我們就可以在多個頁面中複用了。

在這裏插入圖片描述

# 如何封裝這類組件呢?slot

它們也很多=區別==,但是也有很多共性

  • 如果,我們每一個單獨去封裝一個組件,顯然不合適:比如每個頁面都返回,這部分內容我們就要重複去封裝。
  • 但是,如果我們封裝成一個,好像也不合理:有些左側是菜單,有些是返回,有些中間是搜索,有些是文字,等等。

如何封裝合適呢?抽取共性,保留不同求同存異

  • 最好的封裝方式就是將共性抽取到組件中,將不同暴露爲插槽。
  • 一旦我們預留了插槽,就可以讓使用者根據自己的需求,決定插槽中插入什麼內容。
  • 是搜索框,還是文字,還是菜單。由調用者自己來決定。

這就是爲什麼我們要學習組件中的插槽slot的原因。

# slot基本使用

在模板裏面添加 <slot></slot> 標籤

父組件調用的時候,在子組件標籤內添加內容(如下)

<body>

  <!-- 2.父組件模板 -->
  <div id='app'>
    <cpn><button>按鈕</button></cpn>
    <cpn>
      <font color='red'>哈哈哈</font>
    </cpn>
    <cpn><a href="www.baidu.com">百度一下</a></cpn>
    <cpn>
      <p>Eveniet perspiciatis officia voluptate. Temporibus aut ut. Voluptas quasi corporis et assumenda voluptatum.
        Nisi rerum accusantium repudiandae illo. Ut dolor nemo velit veniam sunt exercitationem et eum ipsam.

        Eligendi a repudiandae voluptatum quae consequatur. Quo vel esse cum doloremque voluptatem. Reiciendis est ut
        blanditiis impedit soluta est dolorem consequatur. Quia delectus sint ut illum exercitationem unde et. Nostrum
        adipisci eveniet laudantium modi eligendi laudantium tenetur quo.

        Ipsum sed explicabo culpa labore veritatis et architecto incidunt ea. Voluptas harum et quo ut est adipisci
        itaque ipsum similique. Cumque magnam animi laborum perspiciatis non totam non culpa. Asperiores perspiciatis
        voluptatibus dolorem illo sunt qui dolore nobis.
      </p>
    </cpn>
  </div>

  <!-- 1.子組件模板 -->
  <template id="cpn">
    <div>
      <h2>我是組件</h2>
      <p>下面是插槽</p>
      <slot></slot>
    </div>
  </template>

  <script src="../dist/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
    }
    const app = new Vue({
      el: '#app',
      data: {},
      components: {
        cpn: cpn
      }
    })
  </script>
</body>

在這裏插入圖片描述

# slot 默認值

可以在 <slot></slot> 中添加內容,表示默認值

當用子組件時候,沒有在 slot 中添加東西,則用默認值(如下圖)

<body>

  <!-- 2.父組件模板 -->
  <div id='app'>
    <!-- 不寫東西,則使用默認值 -->
    <cpn></cpn>
    <cpn></cpn>
    <cpn><a href="www.baidu.com">百度一下</a></cpn>
    <cpn>
      <p>Eveniet perspiciatis officia voluptate. Temporibus aut ut. Voluptas quasi corporis et assumenda voluptatum.
        Nisi rerum accusantium repudiandae illo. Ut dolor nemo velit veniam sunt exercitationem et eum ipsam.

        Eligendi a repudiandae voluptatum quae consequatur. Quo vel esse cum doloremque voluptatem. Reiciendis est ut
        blanditiis impedit soluta est dolorem consequatur. Quia delectus sint ut illum exercitationem unde et. Nostrum
        adipisci eveniet laudantium modi eligendi laudantium tenetur quo.

        Ipsum sed explicabo culpa labore veritatis et architecto incidunt ea. Voluptas harum et quo ut est adipisci
        itaque ipsum similique. Cumque magnam animi laborum perspiciatis non totam non culpa. Asperiores perspiciatis
        voluptatibus dolorem illo sunt qui dolore nobis.
      </p>
    </cpn>
  </div>

  <!-- 1.子組件模板 -->
  <template id="cpn">
    <div>
      <h2>我是組件</h2>
      <p>下面是插槽</p>
      <slot>
        <!-- 添加默認值 -->
        <button>默認按鈕</button>
      </slot>
    </div>
  </template>

  <script src="../dist/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
    }
    const app = new Vue({
      el: '#app',
      data: {},
      components: {
        cpn: cpn
      }
    })
  </script>
</body>

在這裏插入圖片描述

# 具名插槽 name

子組件的插槽可能並非是一個。
比如我們封裝一個導航欄的子組件,可能就需要三個插槽,分別代表左邊、中間、右邊。
那麼,外面在給插槽插入內容時,如何區分插入的是哪一個呢?
這個時候,我們就需要給插槽起一個名字

  • 如何使用具名插槽呢?
    非常簡單,只要給slot元素一個name屬性即可
    <slot name='myslot'></slot>

我們來給出一個案例:

<body>

  <!-- 2.父組件模板 -->
  <div id='app'>
    <cpn><a href="www.baidu.com" slot="left">百度一下</a></cpn>
    <cpn><a href="www.baidu.com" slot="center">百度一下</a></cpn>
    <cpn><a href="www.baidu.com" slot="right">百度一下</a></cpn>
  </div>

  <!-- 1.子組件模板 -->
  <template id="cpn">
    <div>
      <slot name='left'>左邊</slot>
      <slot name='center'>中間</slot>
      <slot name='right'>右邊</slot>
    </div>
  </template>

  <script src="../dist/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
    }
    const app = new Vue({
      el: '#app',
      data: {},
      components: {
        cpn: cpn
      }
    })
  </script>
</body>

在這裏插入圖片描述

這裏我們先不對導航組件做非常複雜的封裝,先了解具名插槽的用法。

# 作用域插槽(2.5以前:slot-scope)【廢棄】

需求:父組件替換插槽的標籤,但是內容由子組件來提供。

例子:
.
子組件中包括一組數據,比如:pLanguages: [‘JavaScript’, ‘Python’, ‘Swift’, ‘Go’, ‘C++’]
.
需要在多個界面進行展示:

  • 某些界面是以水平方向一一展示的,
  • 某些界面是以列表形式展示的,
  • 某些界面直接展示一個數組

.
內容在子組件,希望父組件告訴我們如何展示,怎麼辦呢?

利用 slot 作用域插槽就可以了

<body>

  <!-- 2.父組件模板 -->
  <div id='app'>
    <!--默認樣式-->
    <cpn></cpn>
    <cpn>
      <!--
        2.5以下,必須使用template標籤。以上的可以省略
        2.6以上,已廢除slot、slot-scope
      -->
      <template slot-scope='slot'>
        <span v-for='item in slot.data'>{{item}} - </span>
      </template>
    </cpn>
    <cpn>
      <!--
        2.5以下,必須使用template標籤。以上的可以省略
        2.6以上,已廢除slot、slot-scope
      -->
      <template slot-scope='slot'>
        <span>{{slot.data.join(' * ')}}</span>
      </template>
    </cpn>
  </div>

  <!-- 1.子組件模板 -->
  <template id="cpn">
    <div>
      <slot :data='pLanguages'>
        <ul>
          <li v-for="item in pLanguages">{{item}}</li>
        </ul>
      </slot>
    </div>
  </template>

  <script src="../dist/vue.js"></script>
  <script>
    const cpn = {
      template: '#cpn',
      data() {
        return {
          pLanguages: ['JavaScript', 'Python', 'Swift', 'Go', 'C++']
        }
      }
    }
    const app = new Vue({
      el: '#app',
      components: {
        cpn: cpn
      }
    })
  </script>
</body>

在這裏插入圖片描述

# 作用域插槽(2.6版後:v-slot)

  • 官方 插槽 相關 API
  • 官網廢棄 slot 的 說明

在這裏插入圖片描述

  • 【由來】v-slot 完整的由來參見這份 RFC

《vue - 作用域插槽 - 案例 - v-slot (2.6後)》 - https://blog.csdn.net/LawssssCat/article/details/104575116

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章