很多人知道插槽分為三種,但是實際到elementui當中為什麼這麼用,就一臉懵逼,接下來就跟大家聊一聊插槽在elementui中的應用,並且自己寫一個類似el-table的元件
vue的slot分為三種::匿名插槽,具名插槽, 作用域插槽,主要作用:讓父元件可以向子元件指定位置插入 html 結構,也是一種元件間通訊的方式,適用於父元件=>子元件
匿名元件相當於一個預留位置,將父元件的資料傳入子元件的slot標籤內
父元件:
<template>
<ChildSlot>父元件呼叫</ChildSlot>
</template>
<script>
import ChildSlot from "@/components/ChildSlot";
export default {
components:{
ChildSlot
}
}
</script>
子元件:
<template>
<h1>我是子元件</h1>
<slot></slot>
</template>
<script>
export default {
name: "ChildSlot"
}
</script>
執行結果如下:
此時父元件中的「父元件呼叫」這段內容就傳遞到了子元件,並填入了slot挖的坑當中
具名插槽相當於給插槽新增了一個名字(給插槽加入name屬性就是具名插槽)
父元件:
<template>
<child-slot>
<template v-slot:username>我是父元件傳遞的使用者姓名</template>
</child-slot>
<child-slot>
<template v-slot:age>我是父元件傳遞的年齡</template>
</child-slot>
</template>
<script>
import ChildSlot from "@/components/ChildSlot";
export default {
components:{
ChildSlot
}
}
</script>
子元件:
<template>
<h1>我是子元件</h1>
<slot name="username"></slot>
<slot name="age"></slot>
</template>
<script>
export default {
name: "ChildSlot"
}
</script>
執行結果如下:
此時父元件中的根據slot的name,將內容填入了slot挖的坑當中,一個蘿蔔一個坑
與前兩者的不同 slot自定義:name="值" 子元件可向父元件傳遞資訊
父元件:
<template>
<child-slot>
<template v-slot="{username}">我是子元件傳遞的使用者姓名:{{username}}</template>
</child-slot>
</template>
<script>
import ChildSlot from "@/components/ChildSlot";
export default {
components:{
ChildSlot
}
}
</script>
子元件:
<template>
<h1>我是子元件</h1>
<slot :username="username"></slot>
</template>
<script>
export default {
name: "ChildSlot",
data(){
return{
username:'java',
}
}
}
</script>
執行結果如下:
通過作用域插槽,我們可以將子元件中的值傳入到父元件,在父元件進行資料處理後,填坑到子元件
先看一個el-table的例子,當需要對一行中的某一個單元格的內容進行處理的時候,需要用到slot插槽,例如下面的姓名name的處理
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="姓名"
width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
參照el-table,實現我們自己的table元件,講解下為什麼需要用插槽,用了哪些插槽
<el-table
:data="tableData"
style="width: 100%">
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
name: "MyTable"
}
</script>
<template>
<div>
<div>
<!--通過傳遞label標籤,展示表頭-->
<span v-if="label">{{ label }}</span>
</div>
<!--獲取主頁面的data值:$parent.$parent.$data.tableList-->
<div v-for="(user,index) in $parent.$parent.$data.tableList" :key="index">
<!--當傳遞prop屬性的時候,就取user使用者的資料-->
<div v-if="prop">{{user[prop]}}</div>
<!--當不傳遞prop屬性的時候,將使用者的資料通過row屬性,傳遞到父元件當中,也就是app.vue-->
<slot v-else :row="user"></slot>
</div>
</div>
</template>
<script>
export default {
name: "MyTableColumn",
props: {
prop: {type: String},
label: {type: String}
}
}
</script>
我們通過my-table標籤,將內容my-table和my-table-column放置到my-table的匿名插槽中,並通過子元件的props屬性,接收prop和label。如同elementui一樣,如果prop為空,子附件將父元件的user通過作用域插槽傳遞到父元件,並在父元件進行處理
<template>
<div>
<my-table :data="tableList" style="display: flex; flex-direction: row;">
<my-table-column prop="name" label="姓名"></my-table-column>
<my-table-column prop="sex" label="性別"></my-table-column>
<my-table-column label="地址">
<template v-slot="scope">
<span style="background-color: deepskyblue">{{scope.row.address}}</span>
</template>
</my-table-column>
</my-table>
</div>
</template>
<script>
import MyTable from "@/components/MyTable";
import MyTableColumn from "@/components/MyTableColumn";
export default {
name: 'App',
components:{
MyTableColumn,
MyTable
},
data(){
return{
tableList:[
{
name: 'java大師1',
sex: '男',
address: '西藏1'
},
{
name: 'java大師2',
sex: '男',
address: '西藏2'
},
{
name: 'java大師3',
sex: '男',
address: '西藏3'
},
{
name: 'java大師4',
sex: '男',
address: '西藏4'
}
]
}
}
}
</script>
展示結果如下: