1、// 高阶组件HOC
Vue.prototype._update = function (vnode, hydrating) {
var vm = this;
...
// if parent is an HOC, update its $el as well
// 高阶组件HOC
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
vm.$parent.$el = vm.$el;
}
}
解析:
<root>
<child1></child1>
<child2>
<child21></child21>
</child2>
</root>
已child1、child2、child21为例
- $el 当前组件实例对应的DOM
- _vnode 当前组件实例对应的vnode
- $parent 当前组件的父组件实例 child21.parent = child2、child1.\parent = root
- $vnode 子组件在父组件引用节点(组件标签) 所以_vnode.parent = $vnode(源码 Vue.prototype._render 函数赋值),$vnode 和 _vnode 的 $el相同,指向同个DOM
解析:高阶组件HOC
HOC: (component) => ({ template: <component></components>
})
所以component 这个组件 的父节点是HOC,vm(component).$vnode(包括组件标签) = vm(component).$parent(HOC)._vnode(不包含HOC标签),所以需要控制component的HOC组件引用同一个$el
2、$slots、$scopedSlots 差别
- $slots: 子组件的插槽集合,包括具名插槽和默认插槽,$slots内容会直接解析成 vnode 集合给子组件解析获取,所以 $slots中 vnode的上下文context是父组件(调用子组件的组件,不是嵌套子组件的上一级组件)。 因此在 HOC高阶组件 不能直接传递 slots,需要修改slots中的 vnode的context为 HOC组件实例。(child21中的$slots vnode 的context 是 root)
- $scopedSlots: scope-slot会以render函数传递给子组件解析渲染,所使用的上下文context就是 子组件, 因此在 HOC高阶组件 可以直传(透传) $scopedSlots 给子组件。