vue教程:作用域插槽(slot-scope)(父组件定制子组件显示格式) 作者:马育民 • 2022-05-11 17:15 • 阅读:10111 # 提出问题 [](/upload/0/0/1IX8bU5gqix3.png) 父组件使用子组件时,只能向子组件传值,子组件只能显示固定的格式,但是,想在 父组件中, **灵活的 设置 子组件 显示数据的方式** ### 普通子组件的缺点 普通子组件,是将 **数据显示的方式写死**,父组件使用子组件时,只能传值,**无法改变 子组件 显示数据的方式** ### 解决 使用 **作用域插槽** # 作用域插槽 **提示:**本例中为了简单好理解,将 **数据定义在子组件中**,而不是由父组件传给子组件 **数据在子组件中**,当父组件使用该子组件时,父组件还可以控制数据的显示方式,相当于:**父组件定制子组件的显示方式**,这种就需要用到 **作用域插槽** 如下图:左侧是 `app.vue`,右侧是 组件`Article3.vue` [](/upload/0/0/1IX3ICzMuqB6.png) ### 应用场景 element ui 的 [table](https://element.eleme.cn/#/zh-CN/component/table "table") 中的自定义列模板,如下: [](/upload/0/0/1IX3IYQjhWG7.png) ### 好处 类似 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> ``` 显示效果如下: [](/upload/0/0/1IX3ICsyJSCs.png) # 传简单数据、传显示格式 父组件 向 子组件,**即传值**,**又传显示格式** **提示:**这里为了简单好理解,**传一个文章对象**,**而不是传文章数组** 传数据,如下图: [](/upload/0/0/1IX8bU6F9Zu6.png) 传显示格式,如下图: [](/upload/0/0/1IX8bU7HaCkA.png) ### 代码 ##### 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> ``` 原文出处:/show_1IX3ID0v3Wp8.html