您好,登錄后才能下訂單哦!
今天小編給大家分享一下vue插槽能解決的問題是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
vue插槽解決的問題:引入的子組件標簽中間不允許寫內容的。插槽(Slot)是vue為組件的封裝者提供的能力;允許開發者在封裝組件時,把不確定的、希望由用戶指定的部分定義為插槽;可以把插槽認為是組件封裝期間,為用戶預留的內容的占位符。
我們知道,在vue中,引入的子組件標簽中間是不允許寫內容的。為了解決這個問題,官方引入了插槽(slot)的概念。
插槽,其實就相當于占位符。它在組件中給你的HTML模板占了一個位置,讓你來傳入一些東西。插槽又分為匿名插槽、具名插槽以及作用域插槽。
你可能不太明白,為什么我要給子組件中傳入HTML,而不直接寫在子組件中呢?答案是這樣的。你可以想象一個場景,你有五個頁面,這五個頁面中只有一個區域的內容不一樣,你會怎么去寫這五個頁面呢?復制粘貼是一種辦法,但在vue中,插槽(slot)是更好的做法。
匿名插槽,我們又可以叫它單個插槽或者默認插槽。與具名插槽相對,它不需要設置name屬性。(它隱藏的name屬性為default。)
例子:
文件目錄如下,Home組件是HelloWorld的父組件。
在HelloWorld中寫一個匿名插槽
<template>
<div class="hello">
Helloworld組件
<div class = 'slotTxt'>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.hello{
width:100%;
height:300px;
background:#ccc;
margin-top:50px;
.slotTxt{
width:500px;
height:200px;
margin:30px auto;
background:red;
}
}
</style>
在Home組件中引入子組件,并在子組件標簽中寫入內容
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<!-- 沒有插槽,這里的內容不顯示 -->
<h2>我是helloworld中的插槽啊</h2>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
效果
不難看出,HelloWorld標簽中的內容(紅色部分)已經顯示出來了。
上面已經說過,插槽有一個name屬性。與匿名插槽相對,加了name屬性的匿名插槽就是具名插槽。
HelloWorld組件中寫入name屬性分別為left和right的插槽
<template>
<div class="hello">
Helloworld組件
<div class = 'slotLeft'>
<slot name='left'></slot>
</div>
<div class = 'slotRight'>
<slot name='right'></slot>
</div>
</div>
</template>
<script>
export default {
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.hello{
width:700px;
height:300px;
background:#ccc;
margin: 0 auto;
margin-top:50px;
.slotLeft{
width:300px;
height:200px;
float:left;
background:red;
}
.slotRight{
width:300px;
height:200px;
float:right;
background:pink;
}
}
</style>
Home組件通過在template上寫v-slot:name來使用具名插槽
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<template v-slot:left>
<h2>name屬性為left</h2>
</template>
<template v-slot:right>
<h2>name屬性為right</h2>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
注意 v-slot 只能添加在template標簽上 (只有一種例外情況)。
效果
例外情況(被廢棄的slot=‘name’)
帶slot屬性的具名插槽自 2.6.0 起被廢棄,vue3.x被完全廢棄。只有vue3之前的cli可以使用。
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<h2 slot='left'>name屬性為left</h2>
<h2 slot='right'>name屬性為right</h2>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
效果同上。
具名插槽的小知識點
跟 v-on 和 v-bind 一樣,v-slot 也有縮寫,即把參數之前的所有內容 (v-slot:) 替換為字符 #。例如 v-slot:header 可以被重寫為 #header。
作用域插槽其實就是可以傳遞數據的插槽。子組件中的一些數據想在父組件中使用,必須通過規定的方法來傳遞。在官方文檔中提出了一條規則,**父級模板里的所有內容都是在父級作用域中編譯的。子模板里的所有內容都是在子作用域中編譯的。**如果你在父組件直接使用子組件中的值,是會報錯的。
匿名插槽的作用域插槽
為了讓 子組件中的數據 在父級的插槽內容中可用,我們可以將 數據 作為 元素的一個特性綁定上去:
語法:v-bind:users="user"
子組件HelloWorld代碼
<template>
<div class="hello">
Helloworld組件
<div class='slotLeft'>
<slot v-bind:users="user"></slot>
</div>
</div>
</template>
<script>
export default {
data(){
return{
user:{
name:'oralinge',
age:18
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.hello{
width:700px;
height:300px;
background:#ccc;
margin: 0 auto;
margin-top:50px;
.slotLeft{
width:300px;
height:200px;
// float:left;
background:red;
margin:20px auto
}
.slotRight{
width:300px;
height:200px;
float:right;
background:pink;
}
}
</style>
綁定在 元素上的特性(v-bind:users=“user”)被稱為插槽 prop。現在在父級作用域中,我們可以使用帶值的 v-slot 來定義我們提供的插槽 prop 的名字。
語法:v-slot:default="隨意取的名字" // default可省略,簡寫為v-slot="隨意取的名字"
父組件Home代碼
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<template v-slot:default="slotProps">
<h2>{{slotProps.users.name}}</h2>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
注意:
父組件中的slotProps可以是隨意取的。
子組件中users是隨意取的,與之對應的是父組件中的users。
子組件中的user為數據。
效果
具名插槽的作用域插槽
與匿名插槽同理,只需要把default替換成插槽的name值即可。
子組件HelloWorld代碼
<template>
<div class="hello">
Helloworld組件
<div class='slotLeft'>
<slot name='helloWorld' v-bind:users="user"></slot>
</div>
</div>
</template>
<script>
export default {
data(){
return{
user:{
name:'hello world',
age:18
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.hello{
width:700px;
height:300px;
background:#ccc;
margin: 0 auto;
margin-top:50px;
.slotLeft{
width:300px;
height:200px;
// float:left;
background:red;
margin:20px auto
}
.slotRight{
width:300px;
height:200px;
float:right;
background:pink;
}
}
</style>
父組件Home代碼
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<template v-slot:helloWorld="slotProps">
<h2>{{slotProps.users.name}}</h2>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
效果
注意:
默認插槽的縮寫語法不能和具名插槽混用,因為它會導致作用域不明確。
另,slot-scope寫法在2.6之后已廢棄,作用與上面相同,在此不做解釋。
上面的寫法是不是覺得有些麻煩?別著急,我們來看一看解構插槽 Prop。
解構插槽 Prop
作用域插槽的內部工作原理是將你的插槽內容包括在一個傳入單個參數的函數里:
function (slotProps) {
// 插槽內容
}
這意味著 v-slot 的值實際上可以是任何能夠作為函數定義中的參數的 JavaScript 表達式。所以在支持的環境下 (單文件組件或現代瀏覽器),你也可以使用 ES2015 解構來傳入具體的插槽 prop。
語法:v-slot="{ users }"
HelloWold組件
<template>
<div class="hello">
Helloworld組件
<div class='slotLeft'>
<slot v-bind:users="user"></slot>
</div>
</div>
</template>
<script>
export default {
data(){
return{
user:{
name:'hello world',
age:18
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.hello{
width:700px;
height:300px;
background:#ccc;
margin: 0 auto;
margin-top:50px;
.slotLeft{
width:300px;
height:200px;
// float:left;
background:red;
margin:20px auto
}
.slotRight{
width:300px;
height:200px;
float:right;
background:pink;
}
}
</style>
Home組件
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<template v-slot="{ users }">
<h2>{{users.name}}</h2>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
效果
重命名----更改users這個名字
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<template v-slot="{ users:person }">
<h2>{{person.name}}</h2>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
效果如上圖。
定義后備內容,用于插槽 prop 是 undefined 的情形
此處按照官方文檔的寫法會出現語法報錯,后期應該會修復(有知道的麻煩通知一聲)。
<template>
<div class="home">
我是Home父組件
<HelloWorld>
<template >
<h2 v-slot="{ users = { name: '1111' } }">{{users.name}}</h2>
</template>
</HelloWorld>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
}
}
</script>
<style lang="less" scoped>
.home{
width:900px;
margin:0 auto;
background:yellow;
padding-bottom:100px;
}
</style>
復用公共組件
代碼示例如下:
<template>
<div>
<div class="title-box">
<span class="title">{{title}}</span>
<div class="right">
<slot name="right"></slot>
</div>
</div>
<div class="content-box">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data () {
return {
}
},
props: {
title: {
type: String,
required: true
}
}
}
</script>
<style lang="scss" scoped>
.title-box {
padding: 16px 0;
border-bottom: 1px solid #eff1f5;
.title {
font-family: MicrosoftYaHei;
font-size: 24px;
color: #283039;
letter-spacing: 0;
line-height: 24px;
&::before {
width: 4px;
margin-right: 20px;
content: "";
background-color: #5da1ff;
display: inline-block;
height: 20px;
vertical-align: middle;
}
}
.right {
float: right;
margin-right: 20px;
}
}
</style>
使用的ui框架為ivew。
以上就是“vue插槽能解決的問題是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。