How can I duplicate slots within a Vuejs render function?

这一生的挚爱 提交于 2019-12-11 00:57:24

问题


I have a component which is passed content via a slot. I'm using a render function to output the content. The reason I'm using a render function is because I want to duplicate the content multiple times. When I use this code, everything works fine:

render(createElement){
    return createElement('div', {}, this.$slots.default);
}

When I data that is being passed changes, the output changes as well.

However, since I want to duplicate the slot content, I'm now trying this:

return createElement(
    'div', {},
        [
            createElement('div', { }, this.$slots.default),
            createElement('div', { }, this.$slots.default)
        ]
    )

Now the problem is, when the slot content changes from outside the component, only the content in the second div gets updated, the content in the first div stays the same..

Am I missing something here?


回答1:


I can't explain why it happens. But the doc does mention that VNodes Must Be Unique in a render function. See https://vuejs.org/v2/guide/render-function.html#Constraints .

Anyway, this is a Vnode cloning function, which works, which I discovered from https://jingsam.github.io/2017/03/08/vnode-deep-clone.html .

function deepClone(vnodes, createElement) {
    function cloneVNode(vnode) {
        const clonedChildren = vnode.children && vnode
            .children
            .map(vnode => cloneVNode(vnode));
        const cloned = createElement(vnode.tag, vnode.data, clonedChildren);
        cloned.text = vnode.text;
        cloned.isComment = vnode.isComment;
        cloned.componentOptions = vnode.componentOptions;
        cloned.elm = vnode.elm;
        cloned.context = vnode.context;
        cloned.ns = vnode.ns;
        cloned.isStatic = vnode.isStatic;
        cloned.key = vnode.key;
        return cloned;
    }
    const clonedVNodes = vnodes.map(vnode => cloneVNode(vnode))
    return clonedVNodes;
}

How to use it:

render(createElement) {
    return createElement('div', {}, [
        createElement('div', {}, this.$slots.default),
        createElement('div', {}, [...deepClone(this.$slots.default, createElement)])
    ])
}

Demo: https://jsfiddle.net/jacobgoh101/bz3e0o5m/



来源:https://stackoverflow.com/questions/51065172/how-can-i-duplicate-slots-within-a-vuejs-render-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!