在了解插槽之前,我们需要先理解一个概念:编译作用域。
什么是编译作用域呢?
官方的解释是:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译
怎么理解这句话的含义呢?通过一个例子来说明。(偷个懒,不搭环境了)
编译作用域
组件标题
组件内容
最终的结果是:isShow为true,子组件的内容会显示;
这是因为:使用的时候,整个组件的使用过程是相当于在父组件中出现的。作用域就是父组件,使用的属性也是属于父组件的属性。因此,isShow使用的是Vue实例中的属性,而不是子组件的属性。
插槽的目的在于,是组件更具有扩展性。举个栗子,电脑预留的usb接口,可以用来连接多种外部设备,耳机、音响、U盘等等,使得更具有扩展性。插槽slot的作用正是如此,例如,组件中的一个地方,默认情况下为button,而在使用的时候,我们有需求需扩展为span,扩展为input,这时候我们就需要使用到插槽。
最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽。一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容。是搜索框,还是文字,还是菜单。由调用者自己来决定。
//-------------------------- index.vue 父组件
//-------------------分割线--------------------cpn组件:cpn.vue
我是div元素
我是h2元素
子组件预留的slot位置,父组件在使用子组件的时候,在子组件中定义的内容,将渲染在slot的位置处,如果不定义,则不显示。
在上面了解了slot的强大之处后,我们就有一个疑问:如果我想在使用子组件的时候,有多个slot插槽,且想指定添加到想要的slot的位置,那应该怎么处理呢?
再例如:当子组件的功能复杂时,子组件的插槽可能并非是一个。比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?
这时候,我们就需要给slot指定一个name属性,也就是具名插槽。
//-------------------------- index.vue 父组件
中间被替换
//-------------------分割线--------------------cpn组件:cpn.vue
我是左边
我是中间
我是右边
显示效果:
在使用的时候,指定solt的name,就可以替换指定的slot插槽。
官方的定义比较拗口,讲讲自己的理解:
父组件在使用的时候可以替换slot插槽中的显示页面结构,但展示的数据还是来源于子组件。
看一个需求:子组件中包括一组数据,比如:pLanguages: [‘JavaScript’, ‘Python’, ‘Swift’, ‘Go’, ‘C++’]
需要在多个界面进行展示:
1.某些界面是以水平方向一一展示的,
2.某些界面是以列表形式展示的,
3.某些界面直接展示一个数组
内容在子组件,希望父组件告诉我们如何展示,怎么办呢?
//-------------------------- index.vue 父组件
- {
{item}}
{
{slotProps.data.join('-')}}
//-------------------分割线--------------------cpn组件:cpn.vue
我们来看看大型的网站中是怎么时候作用于插槽的:
element-ui中的el-table: element-ui表单 el-table
截取部分代码:
移除
其中的scope代表的就是表格中的一行的数据。
slot插槽在封装组件的过程中,使用的非常频繁,后续有时间再对开发中的一些实用方法进行总结,欢迎补充不足之处,非常感谢。