Vue插槽

  • 1. 初步了解插槽
  • 2. 插槽的分类
    • 2.1 默认插槽
    • 2.2 具名插槽
    • 2.3 作用域插槽

1. 初步了解插槽

什么是插槽?

插槽就是子组件提供给父组件使用的一个占位符,可以通俗理解为“占坑作用”。有了该占位符,父组件可以在该占位符中填充任何模板,不仅限于传递数据,也可以填充如HTML、组件、template模板、标签等。填充后,内容替换子组件的标签

为什么要使用插槽?
在组件通信中(详情见文章:Vue组件学习、组件通信),我们了解到组件之间如何传递数据。那父组件在复用子组件的时候除了想给子组件传递数据,还想更改子组件的内容和样式时,怎么办呢?
一般来说,父组件是没办法更改子组件的内容和样式的,总结就是“你可以用我但是不可以更改我”。
就像买车一样 不能自己去决定车的配置、外观、性能、尺寸,这些都是厂家自己设计好然后批量生产的 ,大家买下都是一样的。

如果你真的想更改子组件,那就使用插槽。
插槽的作用就是使得父组件可以改造子组件,让父组件提供内容,在子组件中展示

使用场景:

  • 使用插槽让用户拓展组件,更好地复用组件和对其做定制化处理。
  • 当一个子组件被父组件复用时,或许在不同情况下需要被更改,此时如果去重写组件是 一件不明智的事情,此时通过slot插槽向子组件内部指定位置传递内容,是一个更好的选择。
  • 在布局组件、表格列、下拉框、弹框显示内容中常用。

插槽的作用:
让父组件向子组件指定位置插入html结构,也是一种组件间的通信方式。

2. 插槽的分类

2.1 默认插槽

案例场景:以下是一个组件的复用(一个蓝色的div即是一个组件),该组件在页面中复用了3次,我想对某一个组件实现私人定制,比如,美食组件我只想放一张图片,电影组件中我想放一个视频,如何做?

由上方效果变成下面这样的:

制定子组件Category.vue:
这是没有使用插槽的情况,组件不能实现定制化:

<template><div class="category"><h3>{{title}}</h3>    <ul><li v-for="(item,index) in listData" :key="index">{{item}}</li></ul></div>
</template>
<script>export default{name:"Category",// 接收父组件传过来的值props:['listData','title']}
</script>
<style>.category{background-color: skyblue;width: 200px;height: 300px;}h3{text-align: center;background-color: orange;}
</style>

在App.vue中使用Category.vue:

<template><div id="app"><!-- 复用子组件 静态传输标题,动态传输数组--><Category title="美食" :listData="foods" /><Category title="书籍" :listData="books"/><Category title="电影" :listData="films"/></div>
</template><script scope="this api replaced by slot-scope in 2.5.0+">
import Category from './components/Category.vue';
export default {name: 'App',components: {Category,},data(){return{// 定义数据foods:['火锅','重庆火锅','小龙虾','牛排'],books:['语文','数学','英语','化学'],films:['重庆森林','七龙珠','犬夜叉','心灵捕手'],}}
}
</script><style>
#app {display: flex;justify-content: space-around;
}
</style>

以上复用只能出现第一个页面效果,见下图:

如果不使用作用域插槽,仅在App.vue更改组件中内容,子组件是不会将内容渲染的
在App.vue中更改子组件内容,此时子组件中无插槽!!!

   <Category title="美食" ><img src="@/assets/hotpot.jpg" alt=""></Category><Category title="书籍" :listData="books"/><Category title="电影" :listData="films"/>

子组件无法渲染在父组件中更改的页面结构,如下图:

下面使用默认插槽:
在子组件Category.vue中定义一个默认插槽:

<template><div class="category"><h3>{{title}}</h3><!-- 定义一个插槽 组件的页面结构完全交给父组件去定义--><slot>默认值,当父组件没有出现时,我会出现</slot></div>
</template>
<script>export default{name:"Category",// 接收父组件传过来的值props:['title']}
</script>
<style>.category{background-color: skyblue;width: 200px;height: 300px;}h3{text-align: center;background-color: orange;}
</style>

App.vue:

<template><div id="app"><!-- 复用子组件 静态传输标题,动态传输数据 --><Category title="美食" ><img src="@/assets/hotpot.jpg" alt=""></Category><!-- <Category title="书籍" :listData="books"/> --><Category title="书籍"><ul><li v-for="(item,index) in books" :key="index">{{item}}</li></ul></Category><!-- <Category title="电影" :listData="films"/> --><Category title="电影"><video src="@/assets/1.mp4" controls></video></Category></div>
</template><script scope="this api replaced by slot-scope in 2.5.0+">
import Category from './components/Category.vue';
export default {name: 'App',components: {Category,},data(){return{// 定义数据foods:['火锅','重庆火锅','小龙虾','牛排'],books:['语文','数学','英语','化学'],films:['重庆森林','七龙珠','犬夜叉','心灵捕手'],}}
}
</script><style>
#app {display: flex;justify-content: space-around;
}
img{width: 100%;
}
video{width: 100%;
}
</style>

注意:对样式的定义,可以定义在父组件也可以定义在子组件。
区别:

  • 定义在父组件,结构先编译好样式再传给子组件;
  • 定义在子组件中,结构传给子组件,再由子组件编译。
<style>
img{width: 100%;
}
video{width: 100%;
}
</style>

2.2 具名插槽

上诉案例中,提高需求,我想在分割线下添加一个跳转链接(分割线以上的都是默认插槽区域),如何做?

使用默认插槽和使用作用域插槽的区别:

具名插槽就是把父组件想要更改的元素插在子组件的某个位置上,并且只接受对应名字的更改元素,而默认插槽则会把父组件的更改元素全盘接收。
使用vue2.6的新语法时,建议使用template模板包裹元素

Category.vue

<template><div class="category"><h3>{{title}}</h3><!-- 定义一个插槽 --><slot>默认值,当父组件没有出现时,我会出现</slot>-------------------------<!-- 声明一个具名插槽 --><slot name="link"></slot><!-- <ul><li v-for="(item,index) in listData" :key="index">{{item}}</li></ul> --></div>
</template>

App.vue

<template><div id="app"><!-- 复用子组件 静态传输标题,动态传输数据 --><Category title="美食" ><img src="@/assets/hotpot.jpg" alt=""><!-- 将元素插入指定名字插槽内 --><!-- vue对具名插槽的新写法 简写形式:#插槽名 --><template ><div class="foot"><a href="">更多美食</a></div></template></Category><!-- <Category title="书籍" :listData="books"/> --><Category title="书籍"><ul><li v-for="(item,index) in books" :key="index">{{item}}</li></ul><!-- 将元素插入指定名字插槽内 --><!-- 传统用法:slot="插槽名" --><div class="foot" slot="link" ><a href="https://www.taobao.com/" >去淘宝</a><a href="https://www.taobao.com/" >去京东</a></div><br><!--<a href="https://www.taobao.com/">去淘宝</a><br><a href="https://www.taobao.com/">去淘宝</a> --></Category><!-- <Category title="电影" :listData="films"/> --><Category title="电影"><video src="@/assets/1.mp4" controls></video><!-- 将元素插入指定名字插槽内--><!-- vue对具名插槽的新写法,v-slot:插槽名--><template v-slot:link><div class="foot"><a href="">经典</a><a href="">热门</a><a href="">推荐</a></div><h4>欢迎前来观影</h4></template></Category></div>
</template><script scope="this api replaced by slot-scope in 2.5.0+">
import Category from './components/Category.vue';
export default {name: 'App',components: {Category,},data(){return{// 定义数据foods:['火锅','重庆火锅','小龙虾','牛排'],books:['语文','数学','英语','化学'],films:['重庆森林','七龙珠','犬夜叉','心灵捕手'],}}
}
</script><style >
#app,.foot{display: flex;justify-content: space-around;
}
img{width: 100%;
}
video{width: 100%;
}
h4{text-align: center;
}
</style>

2.3 作用域插槽

理解: 数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。
案例:

父组件:

<Category title="游戏">
<!-- 一定要使用template模板编译 --><template scope="row"><!-- {{row.games}} --><ul><li v-for="(g, index) in row.games" :key="index">{{ g }}</li></ul></template></Category><Category title="游戏"><!-- 一定要使用template模板编译 --><template scope="row"><ol><li style="color: red" v-for="(g, index) in row.games" :key="index">{{ g }}</li></ol></template></Category><Category title="游戏"><!-- 一定要使用template模板编译 --><template scope="row"><h4 v-for="(g, index) in row.games" :key="index">{{ g }}</h4></template></Category>

子组件中:

   <h3>{{title}}分类</h3><!-- 定义一个作用域插槽 --><slot :games='games'>默认内容</slot><script>export default {props: ['title'],data() {return {games: ['红色警戒', '穿越火线', '劲舞团', '超级玛丽']}}}
</script>

作用域插槽可以看成数据的方向流动,有子组件传给父组件
注意:作用域插槽的使用一定要使用template模板

Vue学习---插槽篇相关推荐

  1. Vue学习-基础篇7

    目录 token函数抽取 在js中使用路由router vue-router 嵌套路由 导航守卫 路由重定向 Vue-router - 路由元信息 路由传参的两种方式 Query Params 路由中 ...

  2. Vue学习笔记进阶篇——Render函数

    本文为转载,原文:Vue学习笔记进阶篇--Render函数 基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编 ...

  3. Vue学习笔记入门篇——数据及DOM

    本文为转载,原文:Vue学习笔记入门篇--数据及DOM 数据 data 类型 Object | Function 详细 Vue 实例的数据对象.Vue 将会递归将 data 的属性转换为 getter ...

  4. vue.js路由配置vue-router的基础学习 - 概念篇

    文章目录 引言 · 相关问题小结: 一.动态路由匹配 (两种情况) A. 两种情况,代码对比: B. 两种情况,效果图对比: C. 提醒 · 仔细体会: D. 优先级的问题: 二.嵌套路由 引言 · ...

  5. Vue学习笔记进阶篇——多元素及多组件过渡

    本文为转载,原文:Vue学习笔记进阶篇--多元素及多组件过渡 多元素的过渡 对于原生标签可以使用 v-if/v-else.但是有一点需要注意: 当有相同标签名的元素切换时,需要通过 key 特性设置唯 ...

  6. java cms 知乎_可能是史上最全面的学习资源 — VUE 开源库篇(二)

    原标题:可能是史上最全面的学习资源 - VUE 开源库篇(二) 原文:https://www.cnblogs.com/opendigg/p/6513510.html 作者:OpenDigg 最近做了一 ...

  7. dropzonejs vue 使用_可能是史上最全面的学习资源 — VUE 开源库篇(一)

    原标题:可能是史上最全面的学习资源 - VUE 开源库篇(一) 原文:https://www.cnblogs.com/opendigg/p/6513510.html 作者:OpenDigg 最近做了一 ...

  8. Vue学习笔记(三)Vue2三种slot插槽的概念与运用 | ES6 对象的解构赋值 | 基于Vue2使用axios发送请求实现GitHub案例 | 浏览器跨域问题与解决

    文章目录 一.参考资料 二.运行环境 三.Vue2插槽 3.1 默认插槽 3.2 具名插槽 3.3 作用域插槽 ES6解构赋值概念 & 作用域插槽的解构赋值 3.4 动态插槽名 四.GitHu ...

  9. VUE源码学习第一篇--前言

    一.目的 前端技术的发展,现在以vue,react,angular为代表的MVVM模式以成为主流,这三个框架大有三分天下之势.react和angular有facebook与谷歌背书,而vue是以一己之 ...

  10. vue-resource post php,Vue学习笔记进阶篇——vue-resource安装及使用

    简介 vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应.也就是说,$.ajax能做的事情,vue-resource插件一样也能做到 ...

最新文章

  1. 《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL
  2. 《java 进阶之路》 上--推荐书籍
  3. NLP新秀:BERT的优雅解读
  4. Kubernetes pod状态出现CrashLoopBackOff 的原因
  5. CF720C Homework(构造)(暴力)
  6. html滚动选择框代码,如何使用最简单纯Css代码美化checkbox复选框、radios单选框和滑动按钮...
  7. stm32倒计时秒表proteus_单片机课程设计倒计时秒表教程文件
  8. php里 \r\n换行问题
  9. Java程序员简历模板,内含个人专业技能和项目经验介绍
  10. php去除富文本编辑器中的内容格式
  11. 史上最新最全面的java大数据学习路线(新手小白必看版本)
  12. Office Ribbon 界面开发入门教程:QtitanRibbon详解
  13. [Linux用户空间编程-5]:用IPTable实现NAT功能
  14. 希捷服务器硬盘格式化不了,希捷硬盘专用分区格式化Seagate DiscWizard16.0 官方版...
  15. 南阳oj入门题-兰州烧饼
  16. html表格宽度设置没效果,html表格宽度设置失效
  17. ESP32学习笔记(18)——光强度GY-30(BH1750)使用
  18. 椭圆曲线加密中定义的加法运算
  19. 阿里云SLB配置HTPPS方式访问
  20. oracle dbms是什么意思,oracle的dbms_stats包详细解说

热门文章

  1. Android沉浸式全面讲解(一)
  2. Linux命令之停机halt
  3. 算法 图8 How Long Does It Take
  4. 泱泱大中华,美丽我的家 - 俗晒网速,感受幸福
  5. (零基础)如何使用python下载哔哩哔哩视频?
  6. 合唱队形java_动态规划之合唱队形问题
  7. self.view.window, self.view.superView的意思
  8. Windows驱动开发第8课(驱动签名与禁用签名打开系统测试模式)
  9. github python抢票_GitHub上抢票工具py12306的使用方法
  10. 笔记本计算机提升性能,如何加快笔记本电脑的运行速度?