深入浅析Vue中的slots/scoped slots
一直对Vue中的slot插槽比较感兴趣,下面是自己的一些简单理解,希望可以帮助大家更好的理解slot插槽
下面结合一个例子,简单说明slots的工作原理
dx-li子组件的template如下:
你好! dx-ul父组件的template如下:结合上述例子以及vue中相关源码进行分析 dx-ul父组件中template编译后,生成的组件render函数: module.exports={ render:function(){ var_vm=this; var_h=_vm.$createElement; var_c=_vm._self._c||_h; //其中_vm.v为createTextVNode创建文本VNode的函数 return_c('ul', [_c('dx-li',[_vm._v("hellojuejin!")])], 1) }, staticRenderFns:[] }
hellojuejin!
传递的插槽内容'hellojuejin!'会被编译成dx-li子组件VNode节点的子节点。
渲染dx-li子组件,其中子组件的render函数:
module.exports={ render:function(){ var_vm=this; var_h=_vm.$createElement; var_c=_vm._self._c||_h; //其中_vm._v函数为renderSlot函数 return_c('li', {staticClass:"dx-li"}, [_vm._t("default",[_vm._v("你好掘金!")])], 2 ) }, staticRenderFns:[] }
初始化dx-li子组件vue实例过程中,会调用initRender函数:
functioninitRender(vm){ ... //其中_renderChildren数组,存储为'hellojuejin!'的VNode节点;renderContext一般为父组件Vue实例 这里为dx-ul组件实例 vm.$slots=resolveSlots(options._renderChildren,renderContext); ... }
其中resolveSlots函数为:
/** *主要作用是将childrenVNodes转化成一个slots对象. */ exportfunctionresolveSlots( children:?Array, context:?Component ):{[key:string]:Array }{ constslots={} //判断是否有children,即是否有插槽VNode if(!children){ returnslots } //遍历父组件节点的孩子节点 for(leti=0,l=children.length;i *编译成span的VNode节点data={attrs:{slot:"abc"},slot:"abc"},所以这里删除该节点attrs的slot */ if(data&&data.attrs&&data.attrs.slot){ deletedata.attrs.slot } /*判断是否为具名插槽,如果为具名插槽,还需要子组件/函数子组件渲染上下文一致。主要作用: *当需要向子组件的子组件传递具名插槽时,不会保持插槽的名字。 *举个栗子: *child组件template: * **
*foo