用render函数开发高阶组件时经常会向下传递插槽,reat使用的是children异常方便,和Vue的插槽(静态插槽、作用域插槽)使用类似。
插槽穿透,大概有三种方式:
// 1.在子组件访问父级插槽
console.log(this.$parent.$slots)
console.log(this.$parent.$scopedSlots)
// 2. 分别传递静态,作用域插槽
render(h) {
console.log(this.$slots)
return h('render-com', {
scopedSlots: {
// 传递作用于插槽
default: props => h('span', props.text)
}
}, [...Object.keys(this.$slots).map(slotName => this.$slots[slotName])]
)
}
// 3.同时传递静态插槽和作用域插槽
render(h) {
const slots = Object.keys(this.$slots).map(slotName =>
this._t(slotName, null, { slot: slotName })
)
return h('render-com', {
}, slots
)
}
注意第三种方式中的this._t
函数,大名是renderSlot
,如果是普通插槽,就直接调用函数生成 vnode,如果是作用域插槽,就直接带着 props 去调用函数生成 vnode。Vue 2.6 版本后对 slot 和 slot-scope 做了一次统一的整合,让它们全部都变为函数的形式,所有的插槽都可以在 this.$scopedSlots
上直接访问。
renderSlot函数
/**
* Runtime helper for rendering <slot>
*/
function renderSlot (
name,
fallback,
props,
bindObject
) {
var scopedSlotFn = this.$scopedSlots[name];
var nodes;
if (scopedSlotFn) { // scoped slot
props = props || {};
if (bindObject) {
if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) {
warn(
'slot v-bind without argument expects an Object',
this
);
}
props = extend(extend({}, bindObject), props);
}
nodes = scopedSlotFn(props) || fallback;
} else {
nodes = this.$slots[name] || fallback;
}
var target = props && props.slot;
if (target) {
return this.$createElement('template', { slot: target }, nodes)
} else {
return nodes
}
}
关于Vue 中 slot 和 slot-scope 的原理,参考大神文章:juejin.cn/post/684490…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!