Vue中插槽的使用
阿新 • • 發佈:2022-05-24
插槽slot
為啥要使用插槽
- 讓我們封裝的元件更加具有擴充套件性。
- 讓使用者可以決定元件內部的一些內容到底展示什麼。
實際案例
-
在移動開發中,幾乎每個頁面都有導航欄,導航欄必然會封裝成一個外掛,比如nav-bar元件。
-
一旦有了這個元件,我們就可以在多個頁面中進行復用。
如何去封裝這類元件呢?
- 他們有很多區別,但也有很多共性。
- 我們單獨去封裝一個元件,顯然不合適:比如每個頁面都有返回,這部分內容我們就要重複去封裝。
- 但是,如果我們封裝成一個,好像也不合理:有些是左側選單,有些是返回,有些中間是搜尋,有些是文字,等等。
抽取共性,保留不同。
- 最好的方法就是將共性抽取到元件中,將不同爆露為插槽。
- 一旦我們預留了插槽,就可以讓使用者根據自己的的需求,決定插槽中的內容。
- 是搜尋框還是文字,還是選單,由呼叫者自己來決定.
例項
- 需求:我想在第三個元件中新增一個按鈕.
<body> <div id="app"> <cpn></cpn> <cpn></cpn> <cpn></cpn> <cpn></cpn> </div> <template id="cpn"> <div> <h2>我是元件</h2> <p>我是元件,哈哈哈</p> <button>按鈕</button> </div> </template> <script> const app = new Vue({ el: '#app', data: { message: '你好帥' }, components: { cpn: { template: '#cpn' } } }) </script> </body>
- 執行截圖
顯然不符合我的預期,所以我們需要定義插槽
- 引入插槽
<body> <div id="app"> <cpn><span>我是插入的sapn標籤</span></cpn> <cpn><i>我是插入的i標籤</i></cpn> <cpn><button>我是插入的按鈕</button></cpn> <cpn><button>我是插入的按鈕</button></cpn> </div> <template id="cpn"> <div> <h2>我是元件</h2> <p>我是元件,哈哈哈</p> <!-- 定義插槽 --> <slot></slot> </div> </template> <script> const app = new Vue({ el: '#app', data: { message: '你好帥' }, components: { cpn: { template: '#cpn' } } }) </script> </body>
- 執行截圖
這次用了插槽,我就可以在元件中插入不同的DOM元素,實現了我的需求
插槽的預設值
<template id="cpn">
<div>
<h2>我是元件</h2>
<p>我是元件,哈哈哈</p>
<!-- 定義插槽 -->
<slot><button>我是預設按鈕</button></slot>
</div>
</template>
當沒有給插槽指定顯示元素時,會顯示預設值,也就是上面的button按鈕
- 如果要在插槽裡顯示多個值,同時放入元件中進行替換,一起作為替換元素.
<body>
<div id="app">
<cpn>
<i>我是插入的i標籤(一)</i>
<h1>我是插入的h1標籤(二)</h1>
<i>我是插入的i標籤(三)</i>
</cpn>
</div>
<template id="cpn">
<div>
<h2>我是元件</h2>
<p>我是元件,哈哈哈</p>
<!-- 定義插槽 -->
<slot><button>我是預設按鈕</button></slot>
</div>
</template>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好帥'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>
</body>
- 執行截圖
可以看到全部替換了
具名插槽slot
使用name
屬性來對插槽進行區別.(和css裡的類名差不多)
<div id="app">
<cpn>
<!-- 只將命名為center的插槽進行了替換 -->
<span slot="center">標題</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>
- 執行截圖
只對中間插槽進行了替換