本人小白,如有问题,还望指出,虚心求教。
使用场景
当在自定义组件设置插槽,特别是具名插槽,如果在使用组件时不为具名插槽指定内容,具名插槽会直接不渲染。
但是如果我们要默认显示内容,就可以直接在 slot 下定义默认内容。
<slot name="title"> --default title-- </slot>
这种使用对于插槽提供默认内容来说,十分方便。
版本问题
但是由于 vue / vue-template-compiler 版本问题,v2.6.13 版本渲染调整,如果vue 与 vue-template-compiler 版本不一致,会导致默认内容渲染不出来。
这时候,需要用 v-if v-else 语法替换原本内容
<slot v-if="$slots.title" name="title"></slot>
<div v-else> --default title-- </div>
源码浅析
v2.6.12
- vue
renderSlot 方法,用来渲染插槽内容
主要差异: 第二个参数类型为 VNode 直接用来渲染节点内容
nodes = this.$slots[name] || fallback,这句话表明优先使用指定的插入内容,如果未指定,则直接使用默认内容
- vue-template-compile
引用 compile 方法编译一段 带有slot 的html
返回ast语法树以及render函数,其他 _t 为 renderSlot 函数
主要差异: 从render 函数可以看到,slot 节点直接渲染成 Vnode
v2.6.13
- vue
renderSlot 方法,用来渲染插槽内容
主要差异: 第二个参数类型为 function/VNode 用来渲染节点内容
nodes = this.$slots[name] || (typeof fallbackRender === 'function' ? fallbackRender() : fallbackRender),这句话表明优先使用指定的插入内容,如果未指定,则直接使用默认内容,判断是否为函数,如果是,则获取函数返回结果,否则,直接使用
- vue-template-compile
引用 compile 方法编译一段 带有slot 的html
返回ast语法树以及render函数,其他 _t 为 renderSlot 函数
主要差异: 从render 函数可以看到,slot 节点渲染成一个函数function,函数function 返回 Vnode
综上所述: 如果不支持slot默认内容,则可能是vue 版本(低版本)和 vue-template-compiler 版本(高版本)不一致导致语法不兼容。解决方法,显而易见了,就是统一版本。