1. 程式人生 > 實用技巧 >5-元件化高階

5-元件化高階

一、插槽 slot

為什麼使用 slot

slot 翻譯為插槽,插槽的目的是讓我們原來的裝置具備更多的擴充套件性;

元件的插槽,也是為了讓我們封裝的元件更加具有擴充套件性,讓使用者可以決定元件內部的一些內容到底展示什麼;


1、slot插槽的基本使用

在子元件中,使用特殊的元素 <slot> 就可以為子元件開啟一個插槽,該插槽插入什麼內容取決於父元件如何使用;

<body>
<div id="app">
  <!--使用預設值-->
  <cpn></cpn>
  <!--替換預設值-->
  <cpn><
p>p標籤</p></cpn> <!--多個值--> <cpn> <div> <h4>Vue</h4> <p>slot插槽</p> </div> </cpn> </div> <template id="cpn"> <div> <h3>元件標題</h3> <p>元件內容</p> <!--插槽, button是插槽中的預設值-->
<slot><button>按鈕</button></slot> </div> </template> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { }, components: { cpn: { template: '#cpn' } } }) </script> </body>
程式碼


2、具名插槽

當子元件的功能複雜時,子元件的插槽可能並非是一個,比如我們封裝一個導航欄的子元件,可能就需要三個插槽,分別代表左邊、中間、右邊,

那麼,外面在給插槽插入內容時,如何區分插入的是哪一個呢?這個時候,我們就需要給插槽起一個名字,這就是具名插槽;

具名插槽的使用很簡單,只要給 slot 元素一個 name 屬性即可:<slot name='myslot'></slot>


<body>
<div id="app">
  <!--預設-->
  <cpn></cpn>
  <!--替換後-->
  <cpn><span slot="left">標題</span></cpn>
</div>

<template id="cpn">
  <div>
    <slot name="left"><span>左邊</span></slot>
    <slot name="center"><span>中間</span></slot>
    <slot name="right"><span>右邊</span></slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {},
    components: {
      cpn: {
        template: '#cpn'
      }
    }
  })
</script>
</body>
程式碼


3、編譯作用域

父元件模板的所有東西,都會在父級作用域內編譯

子元件模板的所有東西,都會在子級作用域內編譯


<body>
<div id="app">
  <!--這裡isShow為true,模板裡的內容可以顯示-->
  <cpn v-show="isShow"></cpn>
</div>

<template id="cpn">
  <div>
    <h4>子元件</h4>
    <!--這裡的isShow為false,按鈕不會顯示-->
    <button v-show="isShow">按鈕</button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      isShow: true
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            isShow: false
          }
        }
      }
    }
  })
</script>
</body>
程式碼


4、作用域插槽

作用域插槽是 slot 一個比較難理解的點,一句話總結就是:

父元件替換插槽的標籤,但是內容由子元件來提供;


<body>
<div id="app">
  <!--預設顯示-->
  <cpn></cpn>

  <!--要求:中間用‘-’連線顯示,使用作用域插槽slot-scope,拿到子元件中的資料-->
  <cpn>
    <template slot-scope="slot">
      <span>{{slot.data.join(' - ')}}</span>  <!--這裡的data就是下面模板裡自定義的data-->
    </template>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot :data="pLanguage">  <!--此處的'data'可以自己定義-->
      <ul>
        <li v-for="item in pLanguage">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {},
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            pLanguage: ['Java', 'Scala', 'Python', 'Go']
          }
        }
      }
    }
  })
</script>
</body>
程式碼