Skip to content

Commit 9ddbbcc

Browse files
committed
wip: scoped slot implementation
1 parent 3575ff4 commit 9ddbbcc

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

flow/component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ declare interface Component {
2525
$children: Array<Component>;
2626
$refs: { [key: string]: Component | Element | Array<Component | Element> | void };
2727
$slots: { [key: string]: Array<VNode> };
28+
$scopedSlots: ?{ [key: string]: () => VNodeChildren };
2829
$vnode: VNode;
2930
$isServer: boolean;
3031

@@ -100,7 +101,7 @@ declare interface Component {
100101
// renderList
101102
_l: (val: any, render: Function) => ?Array<VNode>;
102103
// renderSlot
103-
_t: (name: string, fallback: ?Array<VNode>) => ?Array<VNode>;
104+
_t: (name: string, fallback: ?Array<VNode>, props: ?Object) => ?Array<VNode>;
104105
// apply v-bind object
105106
_b: (data: any, value: any, asProp?: boolean) => VNodeData;
106107
// retrive custom keyCode

src/compiler/codegen/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { genHandlers } from './events'
44
import { baseWarn, pluckModuleFunction } from '../helpers'
55
import baseDirectives from '../directives/index'
6+
import { camelize } from 'shared/util'
67

78
// configurable state
89
let warn
@@ -285,6 +286,10 @@ function genSlot (el: ASTElement): string {
285286
const children = genChildren(el)
286287
return `_t(${slotName}${
287288
children ? `,${children}` : ''
289+
}${
290+
el.attrs ? `${children ? '' : 'null'},{${
291+
el.attrs.map(a => `${camelize(a.name)}:${a.value}`).join(',')
292+
}}` : ''
288293
})`
289294
}
290295

src/core/instance/render.js

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export function initRender (vm: Component) {
1616
vm._staticTrees = null
1717
vm._renderContext = vm.$options._parentVnode && vm.$options._parentVnode.context
1818
vm.$slots = resolveSlots(vm.$options._renderChildren, vm._renderContext)
19+
vm.$scopedSlots = null
1920
// bind the public createElement fn to this instance
2021
// so that we get proper render context inside it.
2122
vm.$createElement = bind(createElement, vm)
@@ -44,6 +45,10 @@ export function renderMixin (Vue: Class<Component>) {
4445
}
4546
}
4647

48+
if (_parentVnode) {
49+
vm.$scopedSlots = _parentVnode.data.scopedSlots
50+
}
51+
4752
if (staticRenderFns && !vm._staticTrees) {
4853
vm._staticTrees = []
4954
}
@@ -183,19 +188,27 @@ export function renderMixin (Vue: Class<Component>) {
183188
// renderSlot
184189
Vue.prototype._t = function (
185190
name: string,
186-
fallback: ?Array<VNode>
191+
fallback: ?Array<VNode>,
192+
props: ?Object
187193
): ?Array<VNode> {
188-
const slotNodes = this.$slots[name]
189-
// warn duplicate slot usage
190-
if (slotNodes && process.env.NODE_ENV !== 'production') {
191-
slotNodes._rendered && warn(
192-
`Duplicate presence of slot "${name}" found in the same render tree ` +
193-
`- this will likely cause render errors.`,
194-
this
195-
)
196-
slotNodes._rendered = true
194+
if (props) { // scoped slot
195+
const scopedSlotFn = this.$scopedSlots[name]
196+
return scopedSlotFn
197+
? scopedSlotFn(props) || fallback
198+
: fallback
199+
} else { // static slot
200+
const slotNodes = this.$slots[name]
201+
// warn duplicate slot usage
202+
if (slotNodes && process.env.NODE_ENV !== 'production') {
203+
slotNodes._rendered && warn(
204+
`Duplicate presence of slot "${name}" found in the same render tree ` +
205+
`- this will likely cause render errors.`,
206+
this
207+
)
208+
slotNodes._rendered = true
209+
}
210+
return slotNodes || fallback
197211
}
198-
return slotNodes || fallback
199212
}
200213

201214
// apply v-bind object

0 commit comments

Comments
 (0)