+48
-9
lines changedFilter options
+48
-9
lines changed Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
1
1
/* @flow */
2
2
3
-
import VNode from './vnode'
3
+
import VNode, { cloneVNode } from './vnode'
4
4
import { createElement } from './create-element'
5
5
import { resolveInject } from '../instance/inject'
6
6
import { normalizeChildren } from '../vdom/helpers/normalize-children'
@@ -32,6 +32,9 @@ export function FunctionalRenderContext (
32
32
// $flow-disable-line
33
33
contextVm._original = parent
34
34
} else {
35
+
// the context vm passed in is a functional context as well.
36
+
// in this case we want to make sure we are able to get a hold to the
37
+
// real context instance.
35
38
contextVm = parent
36
39
// $flow-disable-line
37
40
parent = parent._original
@@ -102,23 +105,28 @@ export function createFunctionalComponent (
102
105
const vnode = options.render.call(null, renderContext._c, renderContext)
103
106
104
107
if (vnode instanceof VNode) {
105
-
setFunctionalContextForVNode(vnode, data, contextVm, options)
106
-
return vnode
108
+
return cloneAndMarkFunctionalResult(vnode, data, renderContext.parent, options)
107
109
} else if (Array.isArray(vnode)) {
108
110
const vnodes = normalizeChildren(vnode) || []
111
+
const res = new Array(vnodes.length)
109
112
for (let i = 0; i < vnodes.length; i++) {
110
-
setFunctionalContextForVNode(vnodes[i], data, contextVm, options)
113
+
res[i] = cloneAndMarkFunctionalResult(vnodes[i], data, renderContext.parent, options)
111
114
}
112
-
return vnodes
115
+
return res
113
116
}
114
117
}
115
118
116
-
function setFunctionalContextForVNode (vnode, data, vm, options) {
117
-
vnode.fnContext = vm
118
-
vnode.fnOptions = options
119
+
function cloneAndMarkFunctionalResult (vnode, data, contextVm, options) {
120
+
// #7817 clone node before setting fnContext, otherwise if the node is reused
121
+
// (e.g. it was from a cached normal slot) the fnContext causes named slots
122
+
// that should not be matched to match.
123
+
const clone = cloneVNode(vnode)
124
+
clone.fnContext = contextVm
125
+
clone.fnOptions = options
119
126
if (data.slot) {
120
-
(vnode.data || (vnode.data = {})).slot = data.slot
127
+
(clone.data || (clone.data = {})).slot = data.slot
121
128
}
129
+
return clone
122
130
}
123
131
124
132
function mergeProps (to, from) {
Original file line number Diff line number Diff line change
@@ -855,4 +855,35 @@ describe('Component slot', () => {
855
855
856
856
expect(vm.$el.textContent).toBe('foo')
857
857
})
858
+
859
+
// #7817
860
+
it('should not match wrong named slot in functional component on re-render', done => {
861
+
const Functional = {
862
+
functional: true,
863
+
render: (h, ctx) => ctx.slots().default
864
+
}
865
+
866
+
const Stateful = {
867
+
data () {
868
+
return { ok: true }
869
+
},
870
+
render (h) {
871
+
this.ok // register dep
872
+
return h('div', [
873
+
h(Functional, this.$slots.named)
874
+
])
875
+
}
876
+
}
877
+
878
+
const vm = new Vue({
879
+
template: `<stateful ref="stateful"><div slot="named">foo</div></stateful>`,
880
+
components: { Stateful }
881
+
}).$mount()
882
+
883
+
expect(vm.$el.textContent).toBe('foo')
884
+
vm.$refs.stateful.ok = false
885
+
waitForUpdate(() => {
886
+
expect(vm.$el.textContent).toBe('foo')
887
+
}).then(done)
888
+
})
858
889
})
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4