因為業務需要,我們的vue組件分了很多層。但我需要在父組件通過slot指定模板,但不在子組件渲染,而是在孫組件或是再下方的組件去渲染。
比如,我有一個通用的A組件,A組件內引用了B組件,B組件又引用了C組件。C組件的模板內有一部分是需要在A組件中來配置的。
因為中間間隔了1層以上的組件,所以沒法通過一般的slot方式解決。於是研究了一下vue的scoped-slots,感慨vue的設計真是很靈活,可以很方便實現。
1、首先,引用A組件的模板:
<div> ...
<A> <span slot="nodeMenu" slot-scope="{node}">{{node.text}}</span>
</A> ... </div>
2.1、如果B組件是模板方式,引用B組件的模板:
<div> ...
<B> <span slot="nodeMenu" slot-scope="{node}"> <slot name="nodeMenu" :node="node"></slot> </span>
</B> ... </div>
2.2、如果B組件是通過render的腳本方式渲染的,可以這樣:
render(h){ return h(ComponentC, { props: { ... }, scopedSlots: self.$scopedSlots, on: { ... } }) }
3、C的模板:
<div v-for="treeNode in nodes"> ... <slot name="nodeMenu" :node="treeNode"></slot> ... </div>
通過分析Vue源碼,Vue的scopedSlots中是一個個渲染函數(並不是VNode)。在B組件中通過這些函數傳遞給C組件,從而實現了跨層傳遞slots。