提出问题
父组件使用子组件时,只能向子组件传值,子组件只能显示固定的格式,但是,想在 父组件中, 灵活的 设置 子组件 显示数据的方式
普通子组件的缺点
普通子组件,是将 数据显示的方式写死,父组件使用子组件时,只能传值,无法改变 子组件 显示数据的方式
解决
使用 作用域插槽
作用域插槽
提示:本例中为了简单好理解,将 数据定义在子组件中,而不是由父组件传给子组件
数据在子组件中,当父组件使用该子组件时,父组件还可以控制数据的显示方式,相当于:父组件定制子组件的显示方式,这种就需要用到 作用域插槽
如下图:左侧是 app.vue,右侧是 组件Article3.vue
应用场景
element ui 的 table 中的自定义列模板,如下:
好处
类似 element-ui 中 table 这种复杂组件,可以在父组件中控制数据的显示方式
代码
Article3.vue
<template>
<div>
<slot :row="obj"></slot>
</div>
</template>
<script>
export default {
data(){
return {
obj:{
name:"百度",
url:"http://www.baidu.com"
}
}
}
}
</script>
App.vue
<template>
<div id="box">
<Article3>
<template slot-scope="scope">
{{scope}}<br>
<a :href="scope.row.url">{{scope.row.name}}</a>
</template>
</Article3>
</div>
</template>
<script>
import Article3 from './views/Article3.vue'
export default
{
name: 'App',
components:{
Article3
}
}
</script>
显示效果如下:
传简单数据、传显示格式
父组件 向 子组件,即传值,又传显示格式
提示:这里为了简单好理解,传一个文章对象,而不是传文章数组
传数据,如下图:
传显示格式,如下图:
代码
TouTiao4子组件
<template>
<ul>
<li >
<slot :row="article"></slot>
</li>
</ul>
</template>
<script>
export default{
name:"TouTiao4",
data: function(){
return {
}
},
props:["article"]
}
</script>
<style>
</style>
app.vue
<template>
<div id="app">
3. 使用组件
<hr />
<TouTiao5 :article="article">
<template slot-scope="scope">
<div>
<a :href="scope.row.url">
{{scope.row.title}}
<div>
{{scope.row.author}}
{{scope.row.time}}
</div>
</a>
</div>
</template>
</TouTiao5>
</div>
</template>
<script>
// import module
// 1 引入组件
import TouTiao5 from './components/TouTiao5.vue'
export default {
name: 'App', // 给当前组件起名
components: {
TouTiao5, // 简化写法
},
data:function(){
return { //数据
article:{
"title":"俄乌大战-",
"author":"BBC",
"time":"2024-09-20",
"comment_num":139,
"url":"https://www.toutiao.com/article/7416298966129754624"
},
}
},
}
</script>
<style>
</style>
传数组、传显示格式
父组件 向 子组件,即传值,又传显示格式
代码
子组件 TouTiao5.vue
<template>
<ul>
<li v-for=" item in articles " :key="item.title">
<slot :row="item"></slot>
</li>
</ul>
</template>
<script>
export default{
name:"TouTiao",
data: function(){
return {
}
},
props:{
articles:Array
}
// props:["articles"]
}
</script>
<style>
</style>
父组件 app.vue
<template>
<div id="app">
3. 使用组件
<hr />
<TouTiao5 :articles="articles">
<template slot-scope="scope">
<div>
<a :href="scope.row.url">
{{scope.row.title}}
<div>
{{scope.row.author}}
{{scope.row.time}}
</div>
</a>
</div>
</template>
</TouTiao5>
</div>
</template>
<script>
// import module
// 1 引入组件
import TouTiao5 from './components/TouTiao5.vue'
export default {
name: 'App', // 给当前组件起名
components: {
TouTiao5, // 简化写法
},
data:function(){
return {
articles:[
{
"title":"俄乌大战-",
"author":"BBC",
"time":"2024-09-20",
"comment_num":139,
"url":"https://www.toutiao.com/article/7416298966129754624"
},
{
"title":"俄乌大战--",
"author":"BBC",
"time":"2024-09-20",
"comment_num":139,
"url":"https://www.toutiao.com/article/7416298966129754624"
},
{
"title":"俄乌大战---",
"author":"BBC",
"time":"2024-09-20",
"comment_num":139,
"url":"https://www.toutiao.com/article/7416298966129754624"
},
{
"title":"俄乌大战----",
"author":"BBC",
"time":"2024-09-20",
"comment_num":139,
"url":"https://www.toutiao.com/article/7416298966129754624"
},
{
"title":"俄乌大战-----",
"author":"BBC",
"time":"2024-09-20",
"comment_num":139,
"url":"https://www.toutiao.com/article/7416298966129754624"
}
]
}
},
}
</script>
<style>
</style>





