7枢劝、使用插槽和具名插槽解決組件內(nèi)容傳遞問(wèn)題
通過(guò)插槽向子組件傳標(biāo)簽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<myform>
<!--這是插槽里的內(nèi)容-->
<div>提交</div>
</myform>
<myform>
<!--這是插槽里的內(nèi)容-->
<button>提交</button>
</myform>
</div>
`
});
app.component('myform',{
methods:{
handleClick(){
alert("大哥劉備駕到!");
}
},
template: `
<div>
<input />
<!--我這里不再真正地寫一個(gè) div 或者 button 而是寫一個(gè) slot-->
<!--<button @click="handleClick">提交</button>-->
<!--注意:slot 是無(wú)法直接綁定事件的,辦法是在其外包括一個(gè) span 標(biāo)簽-->
<span @click="handleClick">
<slot></slot>
</span>
</div>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613173839396.png
除了標(biāo)簽還可以傳遞字符串峰髓、子組件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<myform>
<!--這是插槽里的內(nèi)容-->
<!--<div>提交</div>-->
<!--往插槽傳字符串-->
我是字符串
</myform>
<myform>
<!--這是插槽里的內(nèi)容-->
<!--<button>提交</button>-->
<!--往插槽傳子組件-->
<test />
</myform>
</div>
`
});
app.component('test', {
template: `
<div>Hello World!</div>
`
});
app.component('myform',{
methods:{
handleClick(){
alert("大哥劉備駕到桥状!");
}
},
template: `
<div>
<input />
<!--我這里不再真正地寫一個(gè) div 或者 button 而是寫一個(gè) slot-->
<!--<button @click="handleClick">提交</button>-->
<!--注意:slot 是無(wú)法直接綁定事件的雇初,辦法是在其外包括一個(gè) span 標(biāo)簽-->
<span @click="handleClick">
<slot></slot>
</span>
</div>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613174218424.png
一些說(shuō)明
插槽的作用是將子組件標(biāo)簽內(nèi)部的內(nèi)容替換子組件內(nèi)部的 slot 標(biāo)簽驯击,但是<button>{{message}}</button>
中的 message 所使用的仍然是父組件里面的 message烁兰!
父組件里面里面調(diào)用的數(shù)據(jù)都是父組件里面的,子組件里面里面調(diào)用的數(shù)據(jù)都是子組件里面的余耽!
slot插槽默認(rèn)內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<myform>
<!--這是插槽里的內(nèi)容-->
<!--<div>提交</div>-->
<!--往插槽傳字符串-->
我是字符串
</myform>
<myform>
<!--這是插槽里的內(nèi)容-->
<!--<button>提交</button>-->
<!--往插槽傳子組件-->
<test />
</myform>
<myform>
<!--插槽里的內(nèi)容是空的-->
</myform>
</div>
`
});
app.component('test', {
template: `
<div>Hello World!</div>
`
});
app.component('myform',{
methods:{
handleClick(){
alert("大哥劉備駕到缚柏!");
}
},
template: `
<div>
<input />
<!--我這里不再真正地寫一個(gè) div 或者 button 而是寫一個(gè) slot-->
<!--<button @click="handleClick">提交</button>-->
<!--注意:slot 是無(wú)法直接綁定事件的,辦法是在其外包括一個(gè) span 標(biāo)簽-->
<span @click="handleClick">
<slot>
<!--我們寫一個(gè)默認(rèn)的內(nèi)容-->
<button>插槽默認(rèn)按鈕</button>
</slot>
</span>
</div>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613175053928.png
多個(gè)插槽
具名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<myform>
<!--插槽里的內(nèi)容-->
<template v-slot:header>
<div>header</div>
</template>
<template v-slot:third>
<div>third</div>
</template>
<template v-slot:footer>
<div>footer</div>
</template>
</myform>
</div>
`
});
app.component('myform',{
methods:{
handleClick(){
alert("大哥劉備駕到碟贾!");
}
},
template: `
<div>
<slot name="header"></slot>
<div>
body
<slot name="third"></slot>
</div>
<slot name="footer"></slot>
</div>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613175808942.png
插槽的簡(jiǎn)寫
使用 # 代替 v-slot:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<myform>
<!--插槽里的內(nèi)容,使用 # 代替 v-slot: -->
<template #header>
<div>header</div>
</template>
<template #third>
<div>third</div>
</template>
<template #footer>
<div>footer</div>
</template>
</myform>
</div>
`
});
app.component('myform',{
methods:{
handleClick(){
alert("大哥劉備駕到轨域!");
}
},
template: `
<div>
<slot name="header"></slot>
<div>
body
<slot name="third"></slot>
</div>
<slot name="footer"></slot>
</div>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613180106478.png
作用域插槽
父組件調(diào)用子組件里面的數(shù)據(jù)(子組件將數(shù)據(jù)傳遞給父組件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<!-- 我們使用 v-slot="slotProps" 來(lái)接收子組件傳來(lái)的參數(shù)-->
<list v-slot="slotProps">
<!-- span 里面需要填入 item 袱耽,但是 item 在子組件中-->
<!-- span 里面填入子組件傳過(guò)來(lái)的 item -->
<li>{{slotProps.item}}</li>
</list>
</div>
`
});
app.component('list',{
data(){
return{
list: [1, 2, 3, 4]
}
},
template: `
<!--我們不一定要使用 div 來(lái)完成循環(huán)-->
<!--<div v-for="item in list">{{item}}</div>-->
<!--在子組件中我們將 item 向上從傳遞給父組件-->
<slot v-for="item in list" :item="item"></slot>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613182824077.png
作用域插槽解構(gòu)寫法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue庫(kù) -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
}
},
// slot 插槽
template: `
<div>
<!-- 我們使用 v-slot="slotProps" 來(lái)接收子組件傳來(lái)的參數(shù)-->
<!-- 解構(gòu)簡(jiǎn)寫 -->
<list v-slot="{item}">
<!-- span 里面需要填入 item ,但是 item 在子組件中-->
<!-- span 里面填入子組件傳過(guò)來(lái)的 item -->
<li>{{item}}</li>
</list>
</div>
`
});
app.component('list',{
data(){
return{
list: [1, 2, 3, 4]
}
},
template: `
<!--我們不一定要使用 div 來(lái)完成循環(huán)-->
<!--<div v-for="item in list">{{item}}</div>-->
<!--在子組件中我們將 item 向上從傳遞給父組件-->
<slot v-for="item in list" :item="item"></slot>
`
})
const vm = app.mount('#root');
</script>
</html>
運(yùn)行結(jié)果
image-20210613182953518.png