作者 | Jeskson
來源 | 達達前端小酒館
什么是插槽?插槽的指令為v-slot,它目前取代了slot和slot-scope,插槽內容,vue實例一套內容分發的api,將slot元素作為承載分發內容的出口。
組件的書寫:
<my-link url="/profile">
dada
</my-link>
運用組件模板,可以在里面書寫:
<a v-bind:href="url" class="css-link">
<slot></slot>
</a>
<slot></slot>會替換dada
插槽內可以寫任何模板代碼:
<my-link url="/profile">
<span class=“weixin"> </span>
dada
</my-link>
<my-link url="/profile">
<my-icon name="user"></my-icon>
dada
<my-link>
// 添加圖標組件
如果my-link沒有包含一個slot元素,之間的任何內容都會消失。
什么是插槽,它是vue提出的一個概念,插槽用於決定將所攜帶的內容,插入到指定的某個位置,使得模塊分塊,具有模塊化特質。
插槽怎么用?
// 父組件
<template>
<div>
我是父組件
<slotda>
<p style="color:red">我是父組件得插槽內容</p>
</slotda>
<div>
</template>
在父組件中引用子組件中寫入想要得顯示內容
子組件slotda
<template>
<div class="slotda">
<div>我是slotda組件</div>
<slot></slot>
</idv>
</template>
在子組件中寫入slot,所在位置就是父組件要顯示得內容
// 父組件
<template>
<div>
我是父組件
<slotda>
<p style="color:red">我是父組件插槽內容</p>
<slotdd></slotdd>
</div>
</template>
子組件
<template>
<div class="slotdd">
我是slotdd組件
</div>
</template>
具名插槽
<template>
<div class="slotdadada">
<div>slotdadada</div>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
子組件
父組件
<template>
<div>
我是父組件
<slotdadada>
<p>dada</p>
<template slot="header">
<p>da</p>
</template>
<p slot="footer">我是footer</p>
</slotdadada>
</div>
</template>
插槽默認內容
// 父組件
<template>
<div>
我是父組件
<slotdd></slotdd>
</div>
</template>
子組件
<template>
<div class="slotdd">
<slot>ddd</slot>
</div>
</template>
作用域
<template>
<div>
我是父組件
<slot-d>
<p>{{name}}</p>
</slot-d>
</div>
</template>
<script>
export default {
data() {
return {
name: 'dada'
}
}}
</script>
子組件
<template>
<div class="slot-d">
<slot></slot>
</div>
</template>
插槽可以是任意內容:
插槽就是Vue實現的一套內容分發的API,將
沒有插槽的情況下,在組件標簽內些一些內容是不起任何作用的,當我在組件中聲明了slot元素后,在組件元素內寫的內容就會跑到它這里了!
<div id="app">
<child-component></child-component>
</div>
</script>
Vue.component('child-component', {
template: `
<div>Hello,World!</div>
`
})
let vm = new Vue({
el: '#app',
data:{
}
})
</script>
<child-component>你好</child-component>
組件之間得內容沒有顯示,使用插槽就有顯示了,看看如何用:
Vue.component('child-component',{
template:`
<div>
Hello,World!
<slot></slot>
</div>
`
})
具名插槽,就是給這個插槽起個名字,slot屬性對應的內容都會和組件中name一一對應。
child-component,沒有名字得就是默認得。
<div id="app">
<child-component>
<template slot="girl">
購物、逛街
</template>
<template slot="boy">
帥氣
</template>
<div>
我是人
我是默認的插槽
</div>
</child-component>
</div>
<script>
Vue.component('child-component',{
template:`
<div>
<h4>這個世界有男人和女人</h4>
<slot name="girl"></slot>
<div style="height:1px;background-color:red;"></div>
<slot name="boy"></slot>
<div style="height:1px;background-color:red;"></div>
<slot></slot>
</div>
`
})
let vm = new Vue({
el:'#app',
data:{
}
})
</script>
作用域插槽,在組件上的屬性,可以在組件元素內使用!
在template元素上添加屬性slot-scope
<div id="app">
<child>
<template slot-scope="a">
<!-- {"say":"你好"} -->
{{a}}
</template>
</child>
</div>
Vue.component('child',{
template:`
<div>
<slot say="你好"></slot>
</div>
`
})
<div id="app">
<child :lists="nameList">
<template slot-scope="a">
{{a}}
</template>
</child>
</div>
Vue.component('child',{
props:['lists'],
template:`
<div>
<ul>
<li v-for="list in lists">
<slot :bbbbb="list"></slot>
</li>
</ul>
</div>
`
})
在一個組件中使用
如果組件中沒包含
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<base-layout>
<template slot="header">
<h1>d</h1>
</template>
<p>dd.</p>
<p>dd.</p>
<template slot="footer">
<p> ddd </p>
</template>
</base-layout>
<base-layout>
<h1 slot="header">H</h1>
<p>A.</p>
<p>A.</p>
<p slot="footer">H</p>
</base-layout>
在沒有指定slot屬性的時候 都會放在slot沒有name屬性的插槽當中。
編譯作用域
插槽中的內容不能訪問父級作用域
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
// 部分不能訪問 url
父組件模板的所有東西都會在父級作用域內編譯;子組件模板的所有東西都會在子級作用域內編譯。
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
合成組件:
<div id="app1">
<navigation-link url="/profile">
Your Profile
</navigation-link>
</div>
然后你在 <navigation-link>
的模板中可能會寫為:
Vue.component('navigation-link', {
template: `
<a
v-bind:href="url" rel="external nofollow"
class="nav-link"
>
<slot></slot>
</a>
`
});
當組件渲染的時候,這個
插槽內可以包含任何模板代碼
<navigation-link url="/profile">
<!-- 添加一個 Font Awesome 圖標 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
也可以是組件:
<navigation-link url="/profile">
<!-- 添加一個圖標的組件 -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
但是如果在navigation-link中沒有包含一個slot元素,都會讓之間得內容都消失得。
具名插槽
需要多個插槽
<div class="container">
<header>
<!-- 我們希望把頁頭放這里 -->
</header>
<main>
<!-- 我們希望把主要內容放這里 -->
</main>
<footer>
<!-- 我們希望把頁腳放這里 -->
</footer>
</div>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<base-layout>
<template slot="header">
<h1></h1>
</template>
<p></p>
<p></p>
<template slot="footer">
<p></p>
</template>
</base-layout>
作用域插槽
Vue.component('todo-list',{
template:`
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id">
{{ todo.text }}
</li>
</ul>
`
});
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<!-- 我們為每個 todo 准備了一個插槽,-->
<!-- 將 `todo` 對象作為一個插槽的 prop 傳入。-->
<slot v-bind:todo="todo">
<!-- 回退的內容 -->
{{ todo.text }}
</slot>
</li>
</ul>
看代碼后,插槽內容基本了解。對於編譯作用域:
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
該插槽和模板得其他地方一樣都可以訪問相同的實例屬性,就是相同的”作用域“,但不能訪問navigation-link標簽的作用域。
<navigation-link url="/profile">
Clicking here will send you to: {{ url }}
<!--
這里的 `url` 會是 undefined,因為 "/profile" 是
_傳遞給_ <navigation-link> 的而不是
在 <navigation-link> 組件*內部*定義的。
-->
</navigation-link>
我了解了呢。
后備內容
<button type="submit">
<slot></slot>
</button>
<button type="submit">
<slot>Submit</slot>
</button>
<submit-button></submit-button>
<button type="submit">
Submit
</button>
作用域插槽
<span>
<slot>{{ user.lastName }}</slot>
</span>
<current-user>
{{ user.firstName }}
</current-user>
然而上述代碼不會正常工作,因為只有 <current-user>
組件可以訪問到 user 而我們提供的內容是在父級渲染的。
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
綁定在
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
<current-user v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</current-user>
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>
默認插槽的縮寫語法不能和具名插槽混用
<!-- 無效,會導致警告 -->
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
<template v-slot:other="otherSlotProps">
slotProps is NOT available here
</template>
</current-user>
多個插槽的寫法:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user>
解構插槽 Prop
function (slotProps) {
// 插槽內容
}
<current-user v-slot="{ user }">
{{ user.firstName }}
</current-user>
<current-user v-slot="{ user: person }">
{{ person.firstName }}
</current-user>
動態插槽名
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
❤️ 不要忘記留下你學習的腳印 [點贊 + 收藏 + 評論]
作者Info:
【作者】:Jeskson
【原創公眾號】:達達前端小酒館。
【福利】:公眾號回復 “資料” 送自學資料大禮包(進群分享,想要啥就說哈,看我有沒有)!
【轉載說明】:轉載請說明出處,謝謝合作!~
大前端開發,定位前端開發技術棧博客,PHP后台知識點,web全棧技術領域,數據結構與算法、網絡原理等通俗易懂的呈現給小伙伴。謝謝支持,承蒙厚愛!!!
若本號內容有做得不到位的地方(比如:涉及版權或其他問題),請及時聯系我們進行整改即可,會在第一時間進行處理。
請點贊!因為你們的贊同/鼓勵是我寫作的最大動力!
歡迎關注達達的CSDN!
這是一個有質量,有態度的博客