+233
-167
lines changedFilter options
+233
-167
lines changed Original file line number Diff line number Diff line change
@@ -119,6 +119,7 @@ declare type ASTElement = {
119
119
transitionMode?: string | null;
120
120
slotName?: ?string;
121
121
slotTarget?: ?string;
122
+
slotTargetDynamic?: boolean;
122
123
slotScope?: ?string;
123
124
scopedSlots?: { [name: string]: ASTElement };
124
125
Original file line number Diff line number Diff line change
@@ -354,11 +354,12 @@ function genScopedSlots (
354
354
slots: { [key: string]: ASTElement },
355
355
state: CodegenState
356
356
): string {
357
+
const hasDynamicKeys = Object.keys(slots).some(key => slots[key].slotTargetDynamic)
357
358
return `scopedSlots:_u([${
358
359
Object.keys(slots).map(key => {
359
360
return genScopedSlot(key, slots[key], state)
360
361
}).join(',')
361
-
}])`
362
+
}]${hasDynamicKeys ? `,true` : ``})`
362
363
}
363
364
364
365
function genScopedSlot (
Original file line number Diff line number Diff line change
@@ -586,6 +586,7 @@ function processSlotContent (el) {
586
586
const slotTarget = getBindingAttr(el, 'slot')
587
587
if (slotTarget) {
588
588
el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget
589
+
el.slotTargetDynamic = !!(el.attrsMap[':slot'] || el.attrsMap['v-bind:slot'])
589
590
// preserve slot as an attribute for native shadow DOM compat
590
591
// only for non-scoped slots.
591
592
if (el.tag !== 'template' && !el.slotScope) {
@@ -607,8 +608,10 @@ function processSlotContent (el) {
607
608
)
608
609
}
609
610
}
610
-
el.slotTarget = getSlotName(slotBinding)
611
-
el.slotScope = slotBinding.value
611
+
const { name, dynamic } = getSlotName(slotBinding)
612
+
el.slotTarget = name
613
+
el.slotTargetDynamic = dynamic
614
+
el.slotScope = slotBinding.value || `_` // force it into a scoped slot for perf
612
615
}
613
616
} else {
614
617
// v-slot on component, denotes default slot
@@ -637,10 +640,11 @@ function processSlotContent (el) {
637
640
}
638
641
// add the component's children to its default slot
639
642
const slots = el.scopedSlots || (el.scopedSlots = {})
640
-
const target = getSlotName(slotBinding)
641
-
const slotContainer = slots[target] = createASTElement('template', [], el)
643
+
const { name, dynamic } = getSlotName(slotBinding)
644
+
const slotContainer = slots[name] = createASTElement('template', [], el)
645
+
slotContainer.slotTargetDynamic = dynamic
642
646
slotContainer.children = el.children
643
-
slotContainer.slotScope = slotBinding.value
647
+
slotContainer.slotScope = slotBinding.value || `_`
644
648
// remove children as they are returned from scopedSlots now
645
649
el.children = []
646
650
// mark el non-plain so data gets generated
@@ -664,9 +668,9 @@ function getSlotName (binding) {
664
668
}
665
669
return dynamicKeyRE.test(name)
666
670
// dynamic [name]
667
-
? name.slice(1, -1)
671
+
? { name: name.slice(1, -1), dynamic: true }
668
672
// static name
669
-
: `"${name}"`
673
+
: { name: `"${name}"`, dynamic: false }
670
674
}
671
675
672
676
// handle <slot/> outlets
Original file line number Diff line number Diff line change
@@ -224,12 +224,22 @@ export function updateChildComponent (
224
224
}
225
225
226
226
// determine whether component has slot children
227
-
// we need to do this before overwriting $options._renderChildren
228
-
const hasChildren = !!(
227
+
// we need to do this before overwriting $options._renderChildren.
228
+
229
+
// check if there are dynamic scopedSlots (hand-written or compiled but with
230
+
// dynamic slot names). Static scoped slots compiled from template has the
231
+
// "$stable" marker.
232
+
const hasDynamicScopedSlot = !!(
233
+
(parentVnode.data.scopedSlots && !parentVnode.data.scopedSlots.$stable) ||
234
+
(vm.$scopedSlots !== emptyObject && !vm.$scopedSlots.$stable)
235
+
)
236
+
// Any static slot children from the parent may have changed during parent's
237
+
// update. Dynamic scoped slots may also have changed. In such cases, a forced
238
+
// update is necessary to ensure correctness.
239
+
const needsForceUpdate = !!(
229
240
renderChildren || // has new static slots
230
241
vm.$options._renderChildren || // has old static slots
231
-
parentVnode.data.scopedSlots || // has new scoped slots
232
-
vm.$scopedSlots !== emptyObject // has old scoped slots
242
+
hasDynamicScopedSlot
233
243
)
234
244
235
245
vm.$options._parentVnode = parentVnode
@@ -268,7 +278,7 @@ export function updateChildComponent (
268
278
updateComponentListeners(vm, listeners, oldListeners)
269
279
270
280
// resolve slots + force update if has children
271
-
if (hasChildren) {
281
+
if (needsForceUpdate) {
272
282
vm.$slots = resolveSlots(renderChildren, parentVnode.context)
273
283
vm.$forceUpdate()
274
284
}
Original file line number Diff line number Diff line change
@@ -51,13 +51,14 @@ function isWhitespace (node: VNode): boolean {
51
51
52
52
export function resolveScopedSlots (
53
53
fns: ScopedSlotsData, // see flow/vnode
54
+
hasDynamicKeys?: boolean,
54
55
res?: Object
55
-
): { [key: string]: Function } {
56
-
res = res || {}
56
+
): { [key: string]: Function, $stable: boolean } {
57
+
res = res || { $stable: !hasDynamicKeys }
57
58
for (let i = 0; i < fns.length; i++) {
58
59
const slot = fns[i]
59
60
if (Array.isArray(slot)) {
60
-
resolveScopedSlots(slot, res)
61
+
resolveScopedSlots(slot, hasDynamicKeys, res)
61
62
} else {
62
63
res[slot.key] = slot.fn
63
64
}
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ export function normalizeScopedSlots (
14
14
} else {
15
15
res = {}
16
16
for (const key in slots) {
17
-
if (slots[key]) {
17
+
if (slots[key] && key[0] !== '$') {
18
18
res[key] = normalizeScopedSlot(slots[key])
19
19
}
20
20
}
@@ -26,6 +26,7 @@ export function normalizeScopedSlots (
26
26
}
27
27
}
28
28
res._normalized = true
29
+
res.$stable = slots && slots.$stable
29
30
return res
30
31
}
31
32
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